Как запустить преобразование PDI с базой данных из Java?

Я пытаюсь запустить преобразование PDI с использованием базы данных (любой базы данных, но предпочтительнее не SQL) из Java.

Я пытался использовать mongodb и cassandradb и получил недостающие плагины, я уже спрашивал здесь: Запуск PDI Kettle на Java - Mongodb Step Missing Plugins, но пока никто не ответил.

Я также пытался переключиться на базу данных SQL с помощью PostgreSQL, но это все равно не работает. Судя по проведенному мной исследованию, я думаю, что это произошло из-за того, что я не полностью подключил базу данных к Java, но я не нашел ни одного учебника или направления, которое мне подошло бы. Я пробовал следовать указаниям из этого блога: http://ameethpaatil.blogspot.co.id/2010/11/pentaho-data-integration-java-maven.html: но все еще есть некоторые проблемы с репозиторием (потому что у меня его нет, и кажется, быть обязательным).

Преобразования в порядке, когда я запускаю его из Spoon. Это не удалось только тогда, когда я запускаю его с Java.

Может ли кто-нибудь помочь мне, как запустить преобразование PDI с использованием базы данных? Где я ошибся?

Кому-нибудь когда-нибудь удавалось выполнять преобразование PDI с использованием базы данных noSQL и SQL? какую БД использовали?

Извините, если я задал слишком много вопросов, я так в отчаянии. любая информация будет очень признательна. Спасибо.


person M.R. Murazza    schedule 06.10.2015    source источник
comment
Какая ошибка, если вы запустите Java (предоставьте трассировку стека)? Вы уверены, что хост postgres доступен, а postgresql запущен и работает? Драйвер Postgresql jdbc доступен (в пути к классам вашей java-программы)? Вы уверены, что версия совпадает с драйвером postgresql, jvm, postgres?   -  person simar    schedule 06.10.2015
comment
Да, я уверен, я попытался выполнить простой запрос, и он отлично работает. Я не уверен в версии, но как ее проверить? ошибка, которую я получил, не удалось инициализировать вывод таблицы   -  person M.R. Murazza    schedule 08.10.2015
comment
Здесь jdbc.postgresql.org/download.html вы можете найти таблицу со всеми драйверами jdbc и информацией о совместимости версии jdk, версии postgres. Последняя версия Pentaho JDK7 совместима.   -  person simar    schedule 08.10.2015


Ответы (4)


Выполнение заданий PDI из Java довольно просто. Вам просто нужно импортировать все необходимые файлы jar (для баз данных), а затем вызвать класс чайника. Лучший способ, очевидно, использовать «Maven» для управления зависимостью. В файле maven pom.xml просто вызовите драйверы базы данных.

Пример файла Maven будет примерно таким, как показано ниже, при условии, что вы используете Pentaho v5.0.0GA и базу данных как PostgreSQL:

<dependencies>
    <!-- Pentaho Kettle Core dependencies development -->
    <dependency>
        <groupId>pentaho-kettle</groupId>
        <artifactId>kettle-core</artifactId>
        <version>5.0.0.1</version>
    </dependency>
    <dependency>
        <groupId>pentaho-kettle</groupId>
        <artifactId>kettle-dbdialog</artifactId>
        <version>5.0.0.1</version>
    </dependency>
    <dependency>
        <groupId>pentaho-kettle</groupId>
        <artifactId>kettle-engine</artifactId>
        <version>5.0.0.1</version>
    </dependency>
    <dependency>
        <groupId>pentaho-kettle</groupId>
        <artifactId>kettle-ui-swt</artifactId>
        <version>5.0.0.1</version>
    </dependency>
    <dependency>
        <groupId>pentaho-kettle</groupId>
        <artifactId>kettle5-log4j-plugin</artifactId>
        <version>5.0.0.1</version>
    </dependency>

    <!-- The database dependency files. Use it if your kettle file involves database connectivity. -->
    <dependency>
        <groupId>postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>9.1-902.jdbc4</version>
    </dependency>

You can check my blog for more. It works for database connections.

Надеюсь это поможет :)

person Rishu Shrivastava    schedule 06.10.2015
comment
Спасибо за ваш ответ, можете ли вы добавить скриншот вашей трансформации? и поэтому нам не нужно устанавливать DatabaseMeta или что-то из того, что я упоминал ранее? Дело в том, что моя трансформация работала нормально, когда база данных не была задействована. Затем я получил ошибку, не удалось инициализировать шаг: вывод таблицы - person M.R. Murazza; 08.10.2015
comment
Проверьте этот репозиторий git hub: github.com/rishuatgithub/Pentaho/tree/ master/kettle-n-java я приложил весь код. Он также доступен по ссылке в блоге выше. - person Rishu Shrivastava; 08.10.2015

У меня была такая же проблема в приложении, использующем библиотеки Pentaho. Я решил проблему с этим кодом:

Синглтон для инициализации чайника:

import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.exception.KettleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Inicia as configurações das variáveis de ambiente do kettle
 * 
 * @author Marcos Souza
 * @version 1.0
 *
 */
public class AtomInitKettle {

    private static final Logger LOGGER = LoggerFactory.getLogger(AtomInitKettle.class);

    private AtomInitKettle() throws KettleException {
        try {
            LOGGER.info("Iniciando kettle");
            KettleJNDI.protectSystemProperty();
            KettleEnvironment.init();
            LOGGER.info("Kettle iniciado com sucesso");
        } catch (Exception e) {
            LOGGER.error("Message: {} Cause {} ", e.getMessage(), e.getCause());
        }
    }
}

И код, который меня спас:

import java.io.File;
import java.util.Properties;

import org.pentaho.di.core.Const;
import org.pentaho.di.core.exception.KettleException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class KettleJNDI {

    private static final Logger LOGGER = LoggerFactory.getLogger(KettleJNDI.class);

    public static final String SYS_PROP_IC = "java.naming.factory.initial";

    private static boolean init = false;

    private KettleJNDI() {

    }

    public static void initJNDI() throws KettleException {
        String path = Const.JNDI_DIRECTORY;
        LOGGER.info("Kettle Const.JNDI_DIRECTORY= {}", path);

        if (path == null || path.equals("")) {
            try {
                File file = new File("simple-jndi");
                path = file.getCanonicalPath();
            } catch (Exception e) {
                throw new KettleException("Error initializing JNDI", e);
            }
            Const.JNDI_DIRECTORY = path;
            LOGGER.info("Kettle null > Const.JNDI_DIRECTORY= {}", path);
        }

        System.setProperty("java.naming.factory.initial", "org.osjava.sj.SimpleContextFactory");
        System.setProperty("org.osjava.sj.root", path);
        System.setProperty("org.osjava.sj.delimiter", "/");
    }

    public static void protectSystemProperty() {
        if (init) {
            return;
        }

        System.setProperties(new ProtectionProperties(SYS_PROP_IC, System.getProperties()));

        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("Kettle System Property Protector: System.properties replaced by custom properies handler");
        }

        init = true;
    }

    public static class ProtectionProperties extends Properties {

        private static final long serialVersionUID = 1L;
        private final String protectedKey;

        public ProtectionProperties(String protectedKey, Properties prprts) {
            super(prprts);
            if (protectedKey == null) {
                throw new IllegalArgumentException("Properties protection was provided a null key");
            }
            this.protectedKey = protectedKey;
        }

        @Override
        public synchronized Object setProperty(String key, String value) {
            // We forbid changes in general, but do it silent ...
            if (protectedKey.equals(key)) {
                if (LOGGER.isDebugEnabled()) {
                    LOGGER.debug("Kettle System Property Protector: Protected change to '" + key + "' with value '" + value + "'");
                }

                return super.getProperty(protectedKey);
            }

            return super.setProperty(key, value);
        }
    }
}
person Marcos Souza    schedule 16.02.2016

Я думаю, что ваша проблема связана с подключением базы данных. Вы можете настроить преобразование и не использовать JNDI.

public class DatabaseMetaStep {

    private static final Logger LOGGER = LoggerFactory.getLogger(DatabaseMetaStep.class);

     /**
     * Adds the configurations of access to the database
     * 
     * @return
     */
    public static DatabaseMeta createDatabaseMeta() {
        DatabaseMeta databaseMeta = new DatabaseMeta();

        LOGGER.info("Carregando informacoes de acesso");
        databaseMeta.setHostname("localhost");
        databaseMeta.setName("stepName");
        databaseMeta.setUsername("user");
        databaseMeta.setPassword("password");
        databaseMeta.setDBPort("port");
        databaseMeta.setDBName("database");     
        databaseMeta.setDatabaseType("MonetDB"); // sql, MySql ...
        databaseMeta.setAccessType(DatabaseMeta.TYPE_ACCESS_NATIVE);

        return databaseMeta;
    }
}

Затем вам нужно установить для databaseMeta значение Transmeta.

DatabaseMeta databaseMeta = DatabaseMetaStep.createDatabaseMeta();

        TransMeta transMeta = new TransMeta();
        transMeta.setUsingUniqueConnections(true);
        transMeta.setName("ransmetaNeame");

        List<DatabaseMeta> databases = new ArrayList<>();
        databases.add(databaseMeta);
        transMeta.setDatabases(databases);
person Marcos Souza    schedule 17.02.2016

  • Я попробовал ваш код с «трансформацией без jndi» и работает!

Но мне нужно было добавить этот репозиторий в мой pom.xml:

<repositories>
    <repository>
        <id>pentaho-releases</id>
        <url>http://repository.pentaho.org/artifactory/repo/</url>
    </repository>
</repositories>
  • Также, когда я пытаюсь использовать источник данных, у меня возникает эта ошибка: Не удается создать экземпляр класса: org.osjava.sj.SimpleContextFactory [Корневое исключение — java.lang.ClassNotFoundException: org.osjava.sj.SimpleContextFactory]

Полный журнал здесь: https://gist.github.com/eb15f8545e3382351e20.git

[FIX]: добавьте эту зависимость:

<dependency>
    <groupId>pentaho</groupId>
    <artifactId>simple-jndi</artifactId>
    <version>1.0.1</version>
</dependency>
  • После этого возникает новая ошибка:

    transform_with_jndi — Начата отправка для преобразования [transformation_with_jndi] Ввод таблицы.0 — ОШИБКА (версия 5.0.0.1.19046, сборка 1 от 13.09.2013, 13.13.2013, buildguy): Произошла ошибка, обработка будет остановлена: Ввод таблицы .0 — Произошла ошибка при попытке подключения к базе данных Вход таблицы.0 — параметр java.io.File должен быть каталогом. [D:\opt\workspace-eclipse\invoke-ktr-jndi\simple-jndi]

Полный журнал: https://gist.github.com/jrichardsz/9d74c7263f3567ac4b45

[ОБЪЯСНЕНИЕ] Это связано с

KettleEnvironment.init(); 

https://github.com/jrichardsz/pentaho-pdi-spoon-usefull-templates/blob/master/running-etl-transformation-using-java/researching-pentaho-classes/KettleEnvironment.java

Есть инициализация:

        if (simpleJndi) {
          JndiUtil.initJNDI();
}

И в JndiUtil:

String path = Const.JNDI_DIRECTORY;
if ((path == null) || (path.equals("")))

https://github.com/jrichardsz/pentaho-pdi-spoon-usefull-templates/blob/master/running-etl-transformation-using-java/researching-pentaho-classes/JndiUtil.java

И в классе Const:

public static String JNDI_DIRECTORY = NVL(System.getProperty("KETTLE_JNDI_ROOT"), System.getProperty("org.osjava.sj.root"));

https://github.com/jrichardsz/pentaho-pdi-spoon-usefull-templates/blob/master/running-etl-transformation-using-java/researching-pentaho-classes/Const.java

Так что нам нужно установить эту переменную KETTLE_JNDI_ROOT

[ИСПРАВЛЕНО] Небольшое изменение в вашем примере: просто добавьте это

System.setProperty("KETTLE_JNDI_ROOT", jdbcPropertiesPath);

до

KettleEnvironment.init();

Полный пример, основанный на вашем коде:

import java.io.File;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransMeta;

public class ExecuteSimpleTransformationWithJndiDatasource {    

    public static void main(String[] args) {

        String resourcesPath = (new File(".").getAbsolutePath())+"\\src\\main\\resources";
        String ktr_path = resourcesPath+"\\transformation_with_jndi.ktr";

        //KETTLE_JNDI_ROOT could be the simple-jndi folder in your pdi or spoon home.
        //in this example, is the resources folder
        String jdbcPropertiesPath = resourcesPath;

        try {
            /**
             * Initialize the Kettle Enviornment
             */
            System.setProperty("KETTLE_JNDI_ROOT", jdbcPropertiesPath);
            KettleEnvironment.init();

            /**
             * Create a trans object to properly assign the ktr metadata.
             * 
             * @filedb: The ktr file path to be executed.
             * 
             */
            TransMeta metadata = new TransMeta(ktr_path);
            Trans trans = new Trans(metadata);

            // Execute the transformation
            trans.execute(null);
            trans.waitUntilFinished();

            // checking for errors
            if (trans.getErrors() > 0) {
                System.out.println("Erroruting Transformation");
            }

        } catch (KettleException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

Для полного примера проверьте мой канал github:

https://github.com/jrichardsz/pentaho-pdi-spoon-usefull-templates/tree/master/running-etl-transformation-using-java/invoke-transformation-from-java-jndi/src/main/resources

person JRichardsz    schedule 06.10.2015