Создание нового интерпретатора в Zeppelin
В данной статье описан процесс создания Zeppelin-интерпретатора "с нуля". Информация о добавлении интерпретаторов Zeppelin в существующую группу доступна в статье Добавление интерпретатора в группу.
Обзор сценария
Для создания нового интерпретатора необходим класс, наследующий абстрактный класс Interpreter. Данный класс в виде JAR необходимо поместить на хост ADH с компонентом Zeppelin Server. Разработка полноценного интерпретатора, способного корректно обрабатывать пользовательский код из заметок, подразумевает сложную логику и тестирование, что выходит за рамки данной статьи. В приведенном ниже примере представлена базовая реализация интерпретатора с методами-заглушками для демонстрации подключения и работоспособности тестового интерпретатора. Шаги в сценарии подходят для интерпретаторов любой сложности и являются лишь одним из возможных подходов к созданию интерпретатора.
Сценарий, описанный в статье, включает следующие шаги:
-
Клонирование проекта Zeppelin.
-
Создание интерпретатора на базе существующего модуля.
-
Реализация класса
org.apache.zeppelin.interpreter.Interpreter
, упаковка в JAR. -
Добавление интерпретатора на хост ADH.
Шаг 1. Клонирование проекта Zeppelin
В этом примере предполагается использование проекта Zeppelin в качестве базы для создания нового интерпретатора. Такой подход облегчает управление зависимостями и структурой.
-
Склонируйте репозиторий Zeppelin.
$ git clone https://github.com/apache/zeppelin/tree/master
-
Используйте ветку, соответствующую сборке Zeppelin-сервиса. Например:
$ cd zeppelin $ git checkout 0.11.2
Шаг 2. Создание модуля интерпретатора
В этом примере новый интерпретатор создается путем копирования существующего модуля интерпретатора и изменения его содержимого.
-
Скопируйте существующий модуль интерпретатора, например
file
.$ cp -r file ./mycustominterpreter
-
В новом модуле удалите все классы и создайте тестовый Java-класс
CustomInterpreter
, наследующийorg.apache.zeppelin.interpreter.Interpreter
. В данном сценарииCustomInterpreter
представляет собой класс-заглушку, который не парсит пользовательский код из заметок, однако создает записи в логе при вызове методов.Пример CustomInterpreter.javapackage io.arenadata.zeppelin.mycustominterpreter; import org.apache.zeppelin.interpreter.Interpreter; import org.apache.zeppelin.interpreter.InterpreterContext; import org.apache.zeppelin.interpreter.InterpreterException; import org.apache.zeppelin.interpreter.InterpreterResult; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Properties; public class CustomInterpreter extends Interpreter { public CustomInterpreter(Properties properties) { super(properties); Logger logger = LoggerFactory.getLogger(CustomInterpreter.class); } @Override public void open() throws InterpreterException { logger.info("Stub method called: open()"); } @Override public void close() throws InterpreterException { logger.info("Stub method called: close()"); } @Override public InterpreterResult interpret(String st, InterpreterContext context) throws InterpreterException { logger.info("Stub method called: interpret()"); return null; } @Override public void cancel(InterpreterContext context) throws InterpreterException { logger.info("Stub method called: cancel()"); } @Override public FormType getFormType() throws InterpreterException { logger.info("Stub method called: getFormType()"); return null; } @Override public int getProgress(InterpreterContext context) throws InterpreterException { logger.info("Stub method called: getProgress()"); return 0; } }
РЕКОМЕНДАЦИЯКод интерпретаторов, доступных в Zeppelin "из коробки", можно найти в GitHub-репозитории.Теперь проект имеет следующую структуру:
zeppelin/ +---alluxio +---angular +---bigquery +---bin +---build-tools +---cassandra +---conf +---custominterpreter | | pom.xml | | | +---src | | +---main | | | +---java | | | | \---io | | | | \---arenadata | | | | \---zeppelin | | | | \---mycustominterpreter | | | | CustomInterpreter.java <-- Interpreter logic here | | | | | | | \---resources | | | interpreter-setting.json | | | | | \---test | | | \---target +---flink +---flink-cmd +---groovy ... // other modules
-
Так как модуль был полностью скопированной директорией, необходимо немного рефакторинга, а именно:
-
Добавить новый интерпретатор в список модулей в родительском POM (zeppelin/pom.xml). Например:
<module>mycustominterpreter</module>
-
Обновить поля
artifactId
иinterpreter.name
в POM-файле нового модуля (zeppelin/mycustominterpreter/pom.xml). -
В zeppelin/mycustominterpreter/src/main/resources/interpreter-setting.json в поле
className
указать имя нового класса интерпретатора (CustomInterpreter
). Также необходимо задать новые значения дляname
иgroup
. Они будут использоваться для вызова интерпретатора в коде заметок, используя%<interpreter.group>.<interpreter.name>
. Также в этом файле можно задать список параметров интерпретатора, которые будут доступны в Zeppelin UI. Подробная информация о таких параметрах, какeditOnDblClick
иcompletionSupport
доступна в документации Zeppelin. -
Исправить имена пакетов.
-
Удалить тест-классы.
-
Шаг 3. Сборка нового интерпретатора
Соберите проект Zeppelin с помощью Maven:
$ mvn clean package -DskipTests
В директории target нового модуля будет доступен JAR интерпретатора. Необходим Uber-JAR, включающий все зависимости и имеющий следующую структуру:
mycustominterpreter.jar | interpreter-setting.json | +---com | \---google | \--- ... +---javassist | \--- ... +---javax | \--- ... +---jersey | \--- ... +---META-INF | \--- ... +---io +---arenadata \---zeppelin \---mycustominterpreter \---CustomInterpreter.class +---aopalliance +---apache +---slf4j ...
Шаг 4. Импорт JAR интерпретатора в Zeppelin
-
Скопируйте JAR интерпретатора в директорию /usr/lib/zeppelin/interpreter/ на хосте ADH, где установлен компонент Zeppelin Server.
-
Перезапустите сервис Zeppelin. После рестарта Zeppelin новый интерпретатор станет доступен в списке интерпретаторов в UI.
Новый интерпретаторНовый интерпретатор -
Создайте тестовую заметку с новым интерпретатором. При создании заметки выберите новый интерпретатор по умолчанию либо используйте
%mycustominterpreter
в каждом параграфе. В данном сценарии отправка любых данных интерпретатору не вернет результатов, но создаст записи в логах. Используйте логи в /var/log/zeppelin/, чтобы проверить активность тестового интерпретатора, например:
$ grep -r "Stub method called:*" /var/log/zeppelin