Running Kettle Job by Java API

In questo breve articolo vedremo come sia possibile e semplice utilizzare le API di Pentaho Data Integration (Kettle) [1] per eseguire dei Job in precedenza progettati con il designer Spoon[2]. Non sarà oggetto di trattazione dell’articolo la parte di design che riguarda sia le Trasformazioni sia i Job. L’articolo è rivolto a chi già possiede buone conoscenze di base dell’architettura e del funzionamento di Kettle. La versione di riferimento delle API è la 4.1 Community Edition.

1.   Scenario

Consideriamo un ipotetico caso per cui abbiamo la necessità d’integrare all’interno della nostra applicazione Java l’esecuzione di un Job (di ETL[3]) creato precedentemente con lo strumento Spoon. La possibilità di poter eseguire questo scenario c’è data dalle API di Kettle. In Figura 1 e Figura 2 sono mostrati Job e Trasformazione che sono i pezzi del puzzle che in parte costituiscono il nostro scenario d’integrazione. Il processo di ETL ha l’obiettivo di leggere un insieme di dati anagrafici di persone fisiche, su questo insieme applicare una serie di trasformazioni e poi creare un file di output (in formato XML) integrato con l’informazione del codice fiscale. L’informazione aggiuntiva del codice fiscale proviene da un servizio web di pubblico dominio.

Figura 1 Job che esegue la trasformazione per l’integrazione del codice fiscale.

Figura 1 Job che esegue la trasformazione per l’integrazione del codice fiscale.

Figura 2 Trasformazione che integra i dati letti in input con il codice fiscale.

Figura 2 Trasformazione che integra i dati letti in input con il codice fiscale.

Il Job ExecuteCalculateCodiceFiscale illustrato in Figura 1, nello scenario ipotizzato deve essere eseguito dalla nostra applicazione Java. Il Job esegue la Trasformazione indicata in Figura 2, in caso di successo o fallimento esegue l’invio di una notifica via email. I requisiti necessari per portar a termine l’integrazione con la nostra applicazione Java sono:

  • Kettle API 4.1
  • Configurazione dell’ambiente Kettle
  • Accesso al repository di Kettle

L’ambiente di data integration supporta tre tipologie diverse di repository che sono:

  • Kettle Database Repository
  • Kettle File Repository
  • Pentaho Enterprise Repository (disponibile solamente con l’edizione Enterprise di Pentaho)

Il metodo di accesso al repository è garantito attraverso un’unica interfaccia indipendentemente dal tipo di repository. Per i repository basati su db e su file i “driver” di accesso sono disponibili sul core, al contrario, il “driver” di accesso all’Enterprise Repository è disponibile come plugin. E’ fondamentale che l’ambiente di Kettle sia correttamente configurato, in particolare l’environment KETTLE_HOME, su questa directory il motore di Kettle esegue la ricerca e il caricamento dei plugin disponibili.

Figura 3 Overview scenario d’integrazione.

Figura 3 Overview scenario d’integrazione.

2.   Overview sulle Kettle API

Oltre a fornire strumenti di data integration e business intelligence,Kettle, ha un set di API che possono essere utilizzate per scopi d’integrazione. Le API di Kettle sono divise in quattro principali categorie:

  • Core: package che contiene tutte le classi core di Kettle, memorizzate nel file kettle-core.jar.
  • Database: package che contiene le classi riguardanti i data base supportati da Kettle. Le classi sono memorizzate nel file kettle-db.jar.
  • Engine: package che contiene le classi di runtime di Kettle memorizzate nel file kettle-engine.jar.
  • GUI: package che contiene tutte le classi riguardanti l’interfaccia utente (come Spoon) memorizzate nel file kettle-ui-swt.jar.

L’implementazione e la successiva esecuzione dello scenario illustrato in precedenza, richiedono l’utilizzo di un certo set di API o meglio di package, quali:

  • org.pentaho.di.core: package che contiene tutte le classi necessarie all’inizializzazione dell’ambiente operativo di Kettle.
  • org.pentaho.di.job: package che contiene tutte le classi necessarie alla manipolazione (creazione, modifica, esecuzione, etc…) dei Job.
  • org.pentaho.di.repository: package che contiene tutte le classi necessarie per l’accesso al repository dei metadati.

In Figura 4 è mostrato il class diagram delle classi base utilizzate ai fini dell’integrazione, mentre in Figura 4.1 è illustrato il class diagram che mostra le relazioni tra le principali classi che hanno a che vedere con il concetto di repository.

Figura 4 Class Diagram delle classi base di Kettle.

Figura 4 Class Diagram delle classi base di Kettle.

Figura 3.1 Kettle Repository

Figura 4.1 Kettle Repository

3.   Scheletro della classe Java

Dopo aver dato un rapido sguardo alle API di Kettle (quelle di nostro interesse), in questo paragrafo vedremo come costruire uno scheletro di base per una classe Java che sia in grado di eseguire un generico Job. Credo che la cosa migliore per fissare in mente ciò che si vuole ottenere, sia rappresentare tutte le attività necessarie al raggiungimento dell’obiettivo attraverso il diagramma di attività illustrato in Figura 5.

Figura 5 Activity Diagram per l’esecuzione di un Job.

Figura 5 Activity Diagram per l’esecuzione di un Job.

Tutte le attività indicate nel diagramma sono abbastanza chiare da non richiedere successivi approfondimenti, come d’altronde anche lo stesso flusso. L’esecuzione di ogni singola attività si traduce nell’utilizzo di una o più classi del set di API Kettle indicate nel precedente paragrafo.

Andando alla parte puramente pratica, al Listato 1 è mostrata la semplice classe ExecuteGenericJob della nostra ipotetica applicazione Java che è in grado di eseguire uno dei Job definiti nel repository a cui è possibile accedere. Ricordo che il Job di nostro interesse si chiama ExcuteCalculateCodiceFiscale. Nel Listato 1, per ragioni di spazio ho preferito mostrare il solo corpo della classe, indicando le parti di codice core, quelle che rispecchiano le attività indicate nel diagramma di Figura 5.

Listato 1 Corpo della classe Java ExecuteGenericJob (on Gist.GitHub ).

Il codice della classe java illustrato nel Listato 1 rispecchia quanto descritto nel diagramma di attività di Figura 5, ogni blocco di codice evidenziato (indicato con un box numerato) implementa esattamente nell’ordine, quanto descritto dalla relativa attività.

Le informazioni riguardanti il repository cui connettersi, sono disponibili nel file di configurazione repositories.xml. Ricordo che le API di Kettle fanno riferimento alla variabile d’ambiente KETTLE_HOME come base di ricerca per tutti i file di configurazione, occorre quindi assicurarsi che questa variabile d’ambiente sia correttamente impostata. Il tipo di repository utilizzato è basato su data base MySQL. Sono supportati i più comuni tipi di data base per il repository.

Listato 2 Estratto dal file di configurazione del Repository Kettle (repositories.xml on GistGitHub).

E’ consentito definire uno o più repository, ecco il motivo per cui una delle attività svolte dalla classe java è per l’appunto la creazione dell’istanza di un determinato repository (vedi blocco 3 del Listato 1).  Il repository è organizzato per directory, ogni directory contiene quindi oggetti come Job e Trasformazioni, il nostro Job da eseguire risiede all’interno della directory ShirusKettleDirectory (vedi blocco 5 del Listato 1). Il resto del codice della classe java parla da solo da non richiedere altri approfondimenti.

4.   Esecuzione del Job

Ipotizziamo di voler eseguire il nostro Job direttamente dalla console, confezioniamo quindi una classica applicazione java il cui corpo del metodo main contiene l’intero codice java discusso nel precedente paragrafo. Nel Listato 3 è mostrata l’implementazione completa della classe java che è in grado di eseguire uno dei Job definiti nel repository di Kettle. Per ragioni di spazio sono stati omessi alcuni dei blocchi di codice visti nel precedente paragrafo.

 Listato 3 Classe Java per l’esecuzione di un Job Kettle.

Il programma java ExecuteGenericJob richiede un parametro d’input che corrisponde al nome del Job da eseguire.

$ java it.dontesta.lab.jobs.kettle.ExecuteGenericJob ExecuteCalculateCodiceFiscale

Listato 4 Esecuzione del Job ExecuteCalculateCodiceFiscale.

Il comando mostrato nel Listato 4 esegue il programma java passando come argomento il nome del Job. Nei due successivi listati (Listato 5 e Listato 6) sono mostrati gli output generati dal programma java, sia in caso di successo, sia in caso di fallimento, quest’ultimo a causa di un errore di connessione al repository.

 Listato 5 Output generato dal programma java ExecuteGenericJob in caso di successo (on GistGitHub).

Listato 6 Output generato dal programma java ExecuteGenericJob in caso di errore (on GistGitHub).

Il codice d’esempio potrebbe non funzionare correttamente nel caso di repository di tipo Enterprise (il cui accesso è garantito tramite plugin). L’errore è solitamente dovuto a un problema di configurazione della KETTLE_HOME, ovvero, in fase d’inizializzazione dell’ambiente Kettle, tramite il metodo KettleEnvironment.init() avviene la lettura dei plugin e successivo caricamento (vedi Figura 6 e Figura 7).

Figura 6 Eccezione per plugin non disponibile

Figura 6 Eccezione per plugin non disponibile

Figura 7 Errore durante la lettura della configurazione dei repository

Figura 7 Errore durante la lettura della configurazione dei repository

5.   Conclusioni

L’ambiente di Data Integration (Kettle) offerto da Pentaho è davvero interessante, ricco di molte potenzialità. Di uno strumento informatico, una delle qualità che personalmente apprezzo è la possibilità di creare estensioni e punti d’integrazione nel minor tempo possibile, Kettle a mio avviso include questa qualità.

Per coloro il cui mestiere è l’integrazione di sistemi informatici, la prima caratteristica apprezzata è la facilità d’interazione con la cosiddetta “scatola nera”, ecco il motivo per cui ho volutamente introdotto in quest’articolo le API offerte da Kettle, in particolare ho esaltato le parti delle API che sono solitamente utilizzate in tutti gli scenari d’integrazione.


[1] Pentaho Data Integration offre una soluzione ETL utilizzando un approccio innovativo e orientato ai metadati. Con un’intuitiva interfaccia grafica di progettazione, un’architettura scalabile e basata su standard. Per maggiori info consultare il portale http://kettle.pentaho.com/

[2] E’ l’interfaccia grafica per la creazione e la modifica di Job e Trasformazioni. Può essere inoltre utilizzato per eseguire Job e Trasformazioni con la possibilità di fare operazione di debug.

[3] Extract, Transform, Load (ETL) è un’espressione in lingua inglese che si riferisce al processo di estrazione, trasformazione e caricamento dei dati in un sistema di sintesi (data warehouse, data mart, etc…). I dati sono estratti da sistemi sorgenti quali database transazionali (OLTP), comuni file di testo o da altri sistemi informatici (ad esempio, sistemi ERP o CRM).

Antonio Musarra

I began my journey into the world of computing from an Olivetti M24 PC (http://it.wikipedia.org/wiki/Olivetti_M24) bought by my father for his work. Day after day, quickly taking control until … Now doing business consulting for projects in the enterprise application development using web-oriented technologies such as J2EE, Web Services, ESB, TIBCO, PHP.

You may also like...

  • nick

    Ho un piccolo problema. Non mi è ben chiaro dove reperire il set di API.

    È stato semplice reperire i 3 file base di kettle, ubicati nella cartella “lib” del programma.
    kettle-core.jar – kettle-db.jar – kettle-engine.jar – kettle-ui-swt.jar (non necessario).

    Non sono riuscito a reperire, invece i seguenti packages.
    org.pentaho.di.core – org.pentaho.di.job – org.pentaho.di.repository
    Accedendo all’svn, ci sono diversi package org.pentaho.di.core in diverse src folders.

    Inoltre, inserendo anke il package org.pentaho.di.trans, ho la possibilità di eseguire trasformazioni o devo anche aggiungere i file jar contenuti nella cartella libext?

    Grazie 1000!!

    Nick.

  • Giovanni

    Salve sto provando a riprodurre il suo esempio per capire come usare java e tool di kettle insieme.
    Potrei avere il job e la trasormazione che ha fatto cosi da poterli riprodurre nel mio pc ??

    Grazie in anticipo.

    Giovanni.

    • http://musarra.wordpress.com Antonio Musarra

      Ciao Giovanni,
      su GitHub all’indirizzo https://gist.github.com/1417396 trovi quanto mi hai chiesto.

      Bye,
      Antonio.

  • marco

    Grazie mille per la guida.
    - potresti cortesemente chiarire dove va messo il file repository.xml e il significato dei vari attributi in esso contenuti?

    - Facendo riferimento alla versione integrale della classe di cui hai messo il link, eseguendola mi va in nullPointer alla riga 32, ossia all’istruzione: Repository repository = registry.loadClass(RepositoryPluginType.class,
    repositoryMeta, Repository.class);
    Immagini quale errore posso aver fatto ?

    Grazie ancora.

    INFO 12-09 16:03:55,134 – Using “C:UsersM183D~1.PAVAppDataLocalTempvfs_cache” as temporary files store.
    INFO 12-09 16:03:55,298 – RepositoriesMeta – Reading repositories XML file: C:Usersm.pavone.kettlerepositories.xml
    Exception in thread “main” java.lang.NullPointerException
    at org.pentaho.di.core.plugins.PluginRegistry.getPluginId(PluginRegistry.java:465)
    at org.pentaho.di.core.plugins.PluginRegistry.getPlugin(PluginRegistry.java:483)
    at org.pentaho.di.core.plugins.PluginRegistry.loadClass(PluginRegistry.java:253)
    at com.ExecuteGenericJob.main(ExecuteGenericJob.java:34)

    • http://musarra.wordpress.com Antonio Musarra

      Ciao Marco,
      al momento non ho l’ambiente per fare una verifica veloce.
      Potrebbe essere un problema di accesso al file o il nome errato del repository a cui fai riferimento (sul codice).
      Il file XML del repository solitamente è locato nella posizione da te indicata (C:Usersm.pavone.kettlerepositories.xml), questo file è costruito in maniera automatica dall’ambiente di Data Integration di Kettle.

      Bye,
      Antonio.

      RepositoryMeta repositoryMeta = repositoriesMeta.findRepository("1");


      KettleDatabaseRepository
      1
      kettle-amusarra-repository
      Kettle Repository on shirus-pentaho-suite-00

      • marco

        Molte grazie per la risposta!
        Confermo che nella posizione indicata dalla loggata (che per altro non ho definito io) “C:Usersm.pavone.kettlerepositories.xml” c’è effettivamente il file cercato.
        Questo file è quello creato automaticamente da spoon (cioè l’ambiente di data integration) quando si crea per la prima volta la connessione all’ Enterprise Repository di pentaho. Infatti se modifico o cancello questo file, spoon non trova più la connessione e chiede di crearne una nuova. Il file è corretto, infatti spoon si connette con successo al repository utilizzando quel file.
        Tale file ha per me il seguente contenuto:

        PentahoEnterpriseRepository
        LOCAL1
        Enterprise repository locale
        http://localhost:9080/pentaho-di
        N

        La mia prima sorpresa è che non ha la struttura da te indicata nella guida, per il file che chiami repository.xml (forse indichi questo stesso file, che da me si chiama repositories.xml?). Ad esempio infatti non ha i tag mentre ha un direttamente annidato in . Comunque, come già detto, con spoon il file “funziona”, e in base alle loggate credo che venga letto utilizzando più o meno gli stessi metodi invocati da te.

        Ora il problema è che se nel codice java, subito dopo all’istruzione
        repositoriesMeta.readData();

        vado a loggare
        repositoriesMeta.toString()
        mi stampa una stringa vuota,

        se loggo
        repositoriesMeta.getXML()
        ottengo un xml vuoto

        se loggo
        repositoriesMeta.nrRepositories()
        ottengo “0″.

        Quindi deduco che il file xml non viene letto con successo. Il null pointer si verifica a valle di queste istruzioni, nel punto indicato.
        Al momento non saprei cosa fare. Hai qualche idea del perché accade questo? Altrimenti sapresti indicarmi come valorizzare da codice gli attributi necessari per la connessione al repository, bypassando l’xml?
        Molte grazie ancora.

        Marco

      • marco

        Nel mio altro post l’xml non appare.
        Provo a riscriverlo qui togliendo i caratteri “maggiore” e “minore”.

        repositories.xml:

        ? xml version=”1.0″ encoding=”UTF-8″?
        repositories
        repository
        id PentahoEnterpriseRepository /id
        name LOCAL1 /name
        description Enterprise repository locale /description
        repository_location_url http://localhost:9080/pentaho-di /repository_location_url
        version_comment_mandatory N /version_comment_mandatory
        /repository
        /repositories

        La mia prima sorpresa è che non ha la struttura da te indicata nella guida, per il file che chiami repository.xml (forse indichi questo stesso file, che da me si chiama repositories.xml?). Ad esempio infatti non ha i tag “connection” mentre ha un “repository_location_url” direttamente annidato in “repository” “/repository”

        Grazie

        • http://musarra.wordpress.com Antonio Musarra

          Ciao Marco,
          hai ragione, il nome del file xml è repositories.xml. E’ stata una mia svista che ho appena fixato e pubblicato.

          Il codice d’esempio esegue un find del repository a cui connettersi, questo avviene tramite questo metodo:

          RepositoryMeta repositoryMeta = repositoriesMeta.findRepository("1");

          dovresti quindi (se non hai già fatto), sostituire il valore “1″ con il nome del tuo repository, che mi sembra si chiami LOCAL1. Fatta questa modifica dovrebbe funzionare correttamente.

          Fammi sapere,
          Antonio.

  • marco

    Sì, avevo infatti già sostituito il seguente codice:
    RepositoryMeta repositoryMeta = repositoriesMeta.findRepository(“LOCAL1″);

    Ma a valle di questa istruzione repositoryMeta risulta null (ho fatto un controllo), cosa che manda in errore l’istruzione successiva:
    Repository repository = registry.loadClass(RepositoryPluginType.class,
    repositoryMeta, Repository.class);

    Prima di tutto ciò però abbiamo l’istruzione che dovrebbe valorizzare repositoriesMeta:
    repositoriesMeta.readData();

    dopo la quale (dalle loggate di cui parlavo nel post precedente) sembra che però repositoriesMeta sia vuoto…. Mi sembra che ci sia quindi un errore, a prescindere dal nome del repository che viene utilizzato successivamente alla repositoriesMeta.readData();

    Grazie ancora.

    • http://musarra.wordpress.com Antonio Musarra

      Marco,
      è davvero strano. Non appena avrò cinque minuti vedrò di ripristinare l’ambiente e fare una prova.
      Hai provato (magari da eclipse) a fare un debug?
      Mi puoi dire la versione di PDI che utilizzi?

      Bye,
      Antonio.

      • marco

        La mia versione è la 4.1.2.1
        Ho verificato quanto segue (scusa se alla fine si scoprirà che sono io un ignorante imbranato):
        Con Spoon è possibile creare connessioni a tre tipi di repository diversi:
        - Enterprise Repository
        - Kettle Database Repository
        - Kettle file repository

        Prima io utilizzavo il primo dei tre, spoon generava il file xml che ho postato e non funzionava.
        Poi ho provato ad aggiungere un nuovo repository, del terzo tipo (Kettle file repository).
        Il file repositories.xml è diventato (sostituiti i ‘>’ , ‘<' con apicette "):

        "?xml version="1.0" encoding="UTF-8"?"
        "repositories"
        "repository"
        "id"KettleFileRepository"/id"
        "name"KettleRepositoryFile"/name"
        "description"KettleRepository"/description"
        "base_directory"[Path della directory di base del repository]"/base_directory"
        "read_only"N"/read_only"
        "/repository"
        "repository"
        "id"PentahoEnterpriseRepository"/id"
        "name"pentahoEnterpriseRepository"/name"
        "description"EnterpriseRepository"/description"
        "repository_location_url"http://localhost:9080/pentaho-di"/repository_location_url"
        "version_comment_mandatory"N"/version_comment_mandatory"
        "/repository"
        "/repositories"

        In questo caso la classe funziona correttamente e lancia il mio job senza errori. E' normale questo, che non supporta l'enterprise repository?

        • http://musarra.wordpress.com Antonio Musarra

          Ciao Marco,
          sono riuscito a recuperare macchina virtuale + workspace e fare un test con successo.
          E’ vero che Spoon supporta + repository ma l’interfaccia di accesso dovrebbe essere la stessa, quindi funzionare.
          Io utilizzo ad esempio sia su file sia su db, francamente non ho mai provato l’enterprise repository, che ripeto dovrebbe essere lo stesso codice.
          Non appena avrò qualche minuto proverò a fare un test con l’enterprise repository.

          Bye,
          Antonio.

          Esecuzione del Job Kettle via API Java

  • marco

    Credo che l’enterprise repository è disponibile solo sulla versione enterprise di pentaho.
    In questa discussione viene proposta una piccola variante per lanciare il job nel caso di enterprise repository, usando delle classi diverse. Ma né a me né a lui funziona…
    http://forums.pentaho.com/showthread.php?76662-Enterprise-Repository

    La modifica consiste in questo:

    //FOR ENTERPRISE REPOSITORY ——————————————————-
    PurRepositoryLocation purRepositoryLocation = new PurRepositoryLocation(“http://localhost:9080/pentaho-di”);

    //(id, name, description, PurRepositoryLocation, boolean flag)
    PurRepositoryMeta purRepositoryMeta = new PurRepositoryMeta(“PentahoEnterpriseRepository”, “pentahoEnterpriseRepository”, “EnterpriseRepository”, purRepositoryLocation, true );

    PluginRegistry registry = PluginRegistry.getInstance();
    PurRepository repository = (PurRepository) registry.loadClass(RepositoryPluginType.class,purRepositoryMeta,Repository.class);
    if(repository==null) {
    log.logBasic(“repository is null”);
    }
    repository.connect(“joe”, “password”);
    //———————————————————————————

    repository risulta null…

    Per compilare ed eseguire ho dovuto aggiungere nel classpath le librerie
    pur-repository-plugin-1.0.7.jar che si può reperire ad esempio in C:Program Filespentahodesign-toolsdata-integrationpluginsrepositoriespur-repository-plugin

    e pentaho-ee-dsc-core-2.2.2.jar presente in C:Program Filespentahodesign-toolsdata-integrationpluginsrepositoriespur-repository-pluginlib

    Ma sono andato a tentativi, anche su queste inclusioni…

    • http://musarra.wordpress.com Antonio Musarra

      Si Marco,
      l’Enterprise Repository è disponibile solo con l’edizione Enterprise di Pentaho. Nei miei progetti, ho sempre utilizzato la Community Edition perchè più che sufficiente per raggiungere gli obiettivi. Resto dell’idea che l’interfaccia di accesso al repository dovrebbe essere uguale indipendentemente dal tipo di repository (così avviene sia per file sia per db).

      Adesso ho scaricato l’Edizione Enterprise di Pentaho e nei 30giorni spero di trovare il tempo di fare un test con l’Enterprise Directory.
      A questo punto mi sa che uscirà un articolo per il mio blog.

      Ti terrò aggiornato.

      Bye,
      Antonio.

      • marco

        Confermo comunque che il metodo da te descritto funziona bene per i repository Kettle, sia di tipo file che di tipo db (ho provato con MySql).
        Il file repositories.xml nel mio caso era diverso perché non avevo ancora creato una connessione ad un repository di tipo db. Creata questa viene aggiunta la parte “connection” come da te riportato.

        • http://musarra.wordpress.com Antonio Musarra

          Ciao Marco,
          risolto l’arcano!

          Ho ripreso un mia altra macchina virtuale, ed ecco il flash. Kettle ricerca i plugin installati all’interno della KETTLE_HOME che se non impostata correttamente causa il non caricamento dei plugin e la relativa registrazione sul registry. Una volta impostata correttamente la KETTLE_HOME che deve essere ovviamente visibile all’ambiente runtime di Java, il codice d’esempio funziona correttamente mantenendo quindi la stessa interfaccia.

          Ecco la mia KETTLE_HOME /Users/amusarra/.kettle:
          -rw-r–r– 1 amusarra staff 0 13 Set 22:09 db.cache
          -rw-r–r– 1 amusarra staff 1227 31 Gen 2011 kettle.properties
          lrwxr-xr-x 1 amusarra staff 59 16 Set 21:28 plugins -> /Applications/Pentaho/design-tools/data-integration/plugins
          -rw-r–r– 1 amusarra staff 2079 13 Set 23:13 repositories.xml
          -rw-r–r– 1 amusarra staff 2079 13 Set 23:09 repositories_backup.xml
          -rw-r–r– 1 amusarra staff 72 13 Set 22:09 shared.xml
          -rw-r–r– 1 amusarra staff 162 25 Feb 2011 xulSettings.properties

          Ho aggiornato anche l’articolo inserendo qualche nota.

          Bye,
          Antonio.

  • marco

    Grazie, se puoi darci questo aiuto. Su internet fra l’altro non trovo altre guide….

    • http://musarra.wordpress.com Antonio Musarra

      Buongiorno Marco,
      cercherò di essere sintetico e di spiegarmi al meglio.
      Generalmente, per utilizzare le API di Kettle si fa in modo di avere un ambiente tale e quale a quello “Grafico”, la gui. Per ottenere il risultato viene utilizzata la classe KettleEnvironment e in particolare l’istruzione:

      KettleEnvironment.init();

      questa tra le altre cose dovrebbe preoccuparsi di caricare anche i plugins sul Registry (quelli che risiedono all’interno della directory plugin, che nel mio caso è: /Applications/pentaho/design-tools/data-integration/plugins), tra cui PentahoEnterpriseRepository, che ricordo essere un plugin di tipo RepositoryPluginType. Se tutto funzionasse a dovere il codice illustrato nell’articolo funzionerebbe correttamente, senza alcuna modifica. Per qualche motivo il plugin non viene caricato, motivo per cui si ottiene l’eccezione:

      Exception in thread "main" java.lang.NullPointerException
      at org.pentaho.di.core.plugins.PluginRegistry.getPluginId(PluginRegistry.java:465)
      at org.pentaho.di.core.plugins.PluginRegistry.getPlugin(PluginRegistry.java:483)
      at org.pentaho.di.core.plugins.PluginRegistry.loadClass(PluginRegistry.java:253)
      at it.matrix.portaleagenti.kettle.ExecuteGenericJob.main(ExecuteGenericJob.java:39)

      Il metodo registry.loadClass(), dovrebbe infatti restituire l’implementazione dell’interfaccia sulla base dei meta dati del repository, peccato che, la logica del metodo utilizza il registry cercando il plugin per l’id PentahoEnterpriseRepository non trovandolo restituisce null. Esisterebbero due soluzioni:

    • Registrare manualmente il Plugin
    • Istanziare direttamente l’Enterprise Repository, ricordandosi di eseguire l’inizializzazione tramite repository.init(repositoriesMeta) prima della connessione
    • Andando quindi nel pratico, il codice per utilizzare l’enterprise repository, diviene:

      PurRepositoryLocation purreplocation = new PurRepositoryLocation(
      "http://localhost:9080/pentaho-di");
      PurRepositoryMeta repositoriesMeta = new PurRepositoryMeta(
      "PentahoEnterpriseRepository", "2", "2", purreplocation, false);
      PluginRegistry registry = PluginRegistry.getInstance();
      PurRepository repository = new PurRepository();
      log.logBasic("Repository Description: "
      + repositoriesMeta.getDescription());
      repository.init(repositoriesMeta);
      repository.connect("joe", "password");

      Per far funzionare il tuo codice java, sono necessarie le librerie che trovi in /Applications/pentaho/design-tools/data-integration/plugins/repositories/pur-repository-plugin/lib. Ti allego l’output di esecuzione, che poi a me si ferma perchè non ho la licenza!

      L’ideale sarebbe riuscire a capire il motivo per cui il plugin non viene caricato sul Registry, questo si traduce in un codice pulito e indipendente dal tipo di repository. Sinceramente in questo momento non ho molto tempo per indagare. Magari, visto che tu disponi della versione Enterprise, prova a chiedere al supporto.

      Io ti consiglio di non utilizzare l’Enterprise Repository, non hai nessun valore aggiunto rispetto alla soluzione du DB che tra le altra cose è più performante. Considera che l’interfaccia verso l’enterprise repository è basata su Web Service SOAP il cui WSDL è http://localhost:9080/pentaho-di/webservices/unifiedRepository?wsdl.

      Con questo concludo, sperando di essere stato esaustivo nella spiegazione.

      Esempio con Enterprise Repository

  • Marco

    Dunque, intanto grazie per l’aiuto.
    Sono riuscito a riprodurre entrambi gli scenari: quello che prevedeva l’istanza diretta del repository, tramite il codice da te indicato, e quello che prevedeva l’impostazione corretta della variabile d’ambiente. In quest’ultimo caso mi sono accorto che quando eseguo da eclipse la classe java, la variabile KETTLE_HOME non viene letta, ma l’applicazione cerca tutto in C:Usersm.pavone.kettle (nella cartella del mio utente, in windows), dove ho anche tutti gli altri file che hai indicato (repositories.xml, ecc.). Ho dunque predisposto tutto in questa cartella ma mi sono accorto che non vede il folder plugin con un link, ho dovuto perciò copiare in questa cartella tutto il folder “plugin”, preso da C:Program Filespentahodesign-toolsdata-integrationplugins. Il alternativa potevo copiare questo stesso folder nel progetto eclipse, e funziona ugualmente.
    Per far girare il programma senza errori ho dovuto aggiungere al build path i seguenti jar:
    - scannotation-1.0.2.jar
    - javassist.jar
    entrambi presi da c:Program Filespentahodesign-toolsdata-integrationlibext

    Risultato:
    In entrambi i casi, sia con istanza diretta del repository, sia con il codice java già testato per ambiente kettle (con l’accortezza di aggiungere il folder “plugins”), viene superato l’errore di null pointer.
    In entrambi i casi arrivo ad un nuovo errore successivo:

    Exception in thread “main” org.pentaho.di.core.exception.KettleException:
    com.pentaho.commons.dsc.c: license missing, invalid, or expired
    license missing, invalid, or expired

    at org.pentaho.di.repository.pur.PurRepository.connect(SourceFile:307)
    at com.ExecuteGenericJob.main(ExecuteGenericJob.java:74)
    Caused by: com.pentaho.commons.dsc.c: license missing, invalid, or expired
    at com.pentaho.commons.dsc.g.a(SourceFile:48)
    at org.pentaho.di.repository.pur.PurRepositoryMeta.getRepositoryCapabilities(SourceFile:70)
    at org.pentaho.di.repository.BaseRepositorySecurityProvider.(BaseRepositorySecurityProvider.java:28)
    at org.pentaho.di.repository.pur.d.(SourceFile:20)
    at org.pentaho.di.repository.pur.u.(SourceFile:15)
    at org.pentaho.di.repository.pur.PurRepository.connect(SourceFile:282)
    … 1 more

    Non trova la licenza. Ora: io la licenza ce l’ho, ma non capisco che cosa devo fare per fargliela vedere. In C:Program Filespentaho ho un file chiamato .installedLicenses.xml.
    Ho provato a copiarlo sia nella mia directory utente “.kettle” sia nel progetto eclipse. Ma ottengo sempre lo stesso errore. Ti viene qualche idea a riguardo?
    Magari se poi riesco a far funzionare tutto anche con l’enterprise repository scrivo un post riassuntivo sulle impostazioni fatte che può servire a te o ad altri.
    Grazie.

    Marco

    • http://musarra.wordpress.com Antonio Musarra

      Prego Marco.
      Certo che ancora Windows non supporti i link simbolici è davvero incredibile!!! Sui sistemi Unix/Linux sono stata la prima implementazione.
      Per impostazione predefinita, la KETTLE_HOME corrisponde alla $USER_DIR/.kettle. Nel mio caso ho semplicemente creato il link simbolico alla directory dei plugins.
      I due Jar devono essere inclusi nel classpath in quanto servono per gestire le annotazioni (tipo: PluginTypeAnnotation) e il per alcune operazione al livello di byte-code.

      Il file XML installedLicenses.xml contiene informazioni sulle licenze installate. I file della licenza sono quelli con estensione .lic
      Attraverso il programma install_license dovresti verificare se la tua licenza è correttamente installata, per far questo basta eseguire il comando:

      install_license.sh display

      per installare la licenza il comando è:

      install_license.sh install bi-platform-ee.lic

      Io purtroppo non ho una licenza valida per eseguire una test.

      Bye,
      Antonio.

      • Marco

        Risultano installate 4 licenze:
        - Pentaho Analysis Enterprise Edition
        - Pentaho BI Platform Enterprise Edition
        - Pentaho Dashboard Designer
        - Pentaho PDI Enterprise Edition
        Quindi direi che sono in regola, a meno che non me ne manca una… proprio quella giusta, ma non credo.
        Però sembra che l’applicazione a run time non le trova.

        Sia su eclipse, nelle opzioni di run, sia nel sistema, sono settate le seguenti variabili:
        KETTLE_HOME [...]
        PENTAHO_HOME C:Program Filespentaho
        PENTAHO_INSTALLED_LICENSE_PATH C:Program Filespentaho.installedLicenses.xml
        PENTAHO_JAVA_HOME C:Program Filespentahojava
        (tutte corrette)

        • http://musarra.wordpress.com Antonio Musarra

          Marco,
          senza perderci troppo tempo ti consiglio di mandare una mail al supporto di Pentaho. A questo punto si tratta solo di una questione di configurazione.
          Non avendo i sorgenti del package com.pentaho.commons.dsc diviene difficile man non impossibile capire dove va a cercare i file della licenza.

          Bye,
          Antonio.

  • Marco

    Il supporto pentaho si guarda dal rispondere, per ora.
    Comunque c’è una differenza tra l’enterprise repository e gli altri: con il primo è possibile schedulare i job da spoon, con gli altri tipi di repository no.

    Marco

    • http://musarra.wordpress.com Antonio Musarra

      Ho avuto modo di vedere che l’Enterprise Repository è basato su Apache Jackrabbit.
      In teoria il supporto dovrebbe rispondere nel giro di poco, sempre che l’acquisto della licenza include anche il supporto, solitamente dovrebbe essere così. Altrimenti prova a fare un trace dell’applicazione Java per cercare di capire dove cerca la licenza.

      Ma sei il Penty del forum di Pentaho?

      Bye,
      Antonio.

      • Marco

        Sì sono io. Ti ho anche risposto sul forum, ma ancora non è stato pubblicato il mio post.
        Il trace non so come si fa, però ora vedo… a presto, spero.

  • Marco

    Guardando i log del data-integration-server vedo che si verifica questa eccezione quando chiamo il job da remoto:

    INFO 18-09 16:13:30,613 – RepositoriesMeta – Reading repositories XML file: C:.kettlerepositories.xml
    java.lang.Throwable: Missing, invalid, or expired product license: Pentaho Hadoop Enterprise Edition
    ERROR 18-09 16:13:30,715 – Error loading plugin: HIVE/Hadoop Hive{class org.pentaho.di.core.plugins.DatabasePluginType}
    org.pentaho.di.core.exception.KettlePluginException:
    Unexpected error loading class:
    Missing, invalid, or expired product license: Pentaho Hadoop Enterprise Edition

    at org.pentaho.di.core.plugins.PluginRegistry.loadClass(PluginRegistry.java:381)
    at org.pentaho.di.core.plugins.PluginRegistry.loadClass(PluginRegistry.java:240)
    at org.pentaho.di.core.database.DatabaseMeta.getDatabaseInterfacesMap(DatabaseMeta.java:1302)
    at org.pentaho.di.core.database.DatabaseMeta.findDatabaseInterface(DatabaseMeta.java:488)

    Io Non uso hadoop. Il job è semplicissimo. Sto cercando un modo per disabilitare questo plugin… che comunque quando mi connetto al repository da spoon non da problemi…(?)

  • Marco

    Ciao,
    ho contattato il supporto pentaho e, nel tentativo di capire l’origine del problema, mi hanno dato una licenza temporanea anche per Hadoop. Stranamente anche con la licenza installata ottengo la stessa eccezione per licenze mancanti, anche se questa volta il server non logga più eccezioni, a differenza di come faceva prima dell’aggiunta della nuova licenza.
    Allora mi sto chiedendo, non è che devo caricare le licenze lato client in qualche modo, da codice java? Ti viene in mente niente?
    Marco

  • Marco

    RISOLTO IL MISTERO:

    per far funzionare l’invocazione di un job salvato sull’Enterprise repository, tramite api java, da applicazione java stand alone, è necessario definire la variabile di sistema “pentaho.installed.licenses.file” in modo che punti al fine delle licenze .installedLicenses.xml.
    E’ sufficiente quindi aggiungere all’inizio della nostra classe java, già discussa, un’istruzione del tipo:
    System.setProperty(“pentaho.installed.licenses.file”, “[giusto path].installedLicenses.xml”);

    note:
    1) .installedLicenses.xml si trova nella cartella di installazione di pentaho, sulla root.
    2) il valore da associare a pentaho.installed.licenses.file è lo stesso della variabile d’ambiente, comunque necessaria per il funzionamento del programma, PENTAHO_INSTALLED_LICENSE_PATH. Supponendo di averla già settata, si può quindi anche scrivere una cosa del genere:
    System.setProperty(“pentaho.installed.licenses.file”, System.getProperty(“PENTAHO_INSTALLED_LICENSE_PATH”));
    3) tutto ciò funziona su applicazione stand alone. Tentare di eseguire le api java di pentaho da un’applicazione deployata su un application server (nel mio caso jboss) comporta un serie di altri problemi con i quali mi sto scontrando adesso senza alcun successo. Ciao!

    • Marco

      nota 4)
      non era necessaria alcuna licenza per Hadoop!

      • http://musarra.wordpress.com Antonio Musarra

        Img, mi sembrava troppo strano!

    • http://musarra.wordpress.com Antonio Musarra

      Ottimo Marco.
      Certo, pure il supporto che non risponde avendo una licenze enterprise è proprio il colmo.
      Grazie per la condivisione.

      Bye,
      Antonio

      • Marco

        Per la precisione il supporto rispondeva, sebbene non sembravano molto preparati.
        Ma, arrivati a definire qual’era il problema preciso, hanno detto che sa soluzione dello stesso esulava dal supporto standard incluso nel pacchetto acquistato, e che per indicazioni su come utilizzare le api java era necessario acquistare un apposito training (sebbene la risposta, come abbiamo visto, era infondo molto semplice, a saperla).
        Dicevano “se vuoi invocare un job in remoto puoi utilizzare kitchen”. E stop.
        Ciao e grazie!

  • Alex

    Ciao Marco, ho una domanda.
    Se non si utilizza job.waitUntilFinished(); è possibile in un momento successivo verificare se il job è ancora in esecuzione e gli eventuali errori?

    Grazie
    Alex