Дебаг маршрутов Camel в Red Hat Dev Studio или как отпескоструить пескоструй
Блоги
Навигационные полоски
Один мой хороший приятель как-то рассказал мне историю как он подрабатывал промышленным альпинизмом. Ему поступил заказ на чистку труб на каком-то заводе. Он со своими соратниками приехал на объект, им выдали пескоструй, показали трубы. И первое, что он очистил - это сам пескоструй, так как вид грязного девайса противоречил его эстетическим взглядам. Эта история пришла мне на ум когда возникла задача дебага самого процесса дебага. Об этом и хотел бы поведать в блоге.
Часть 1 Погружение в механизм установки брекпоинтов
Для данного блога я использовал следующие инструменты:
- Старенькую Red Hat JBoss Developer Studio 11.3.0.GA
- Старенький Eclipse Oxygen.2 Release (4.7.2)
- Red Hat JBoss Fuse 7.7.0.GA (на Apache Karaf)
Перед запуском студии потребуется добавить следующее в devstudio.ini:
-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000
и только потом запустить. Добавьте в студию тестовый проект с маршрутом Apache Camel.
Далее, импортируйте в Eclipse исходный код из репозитория https://github.com/jbosstools/jbosstools-fuse. В основном нам понадобится проект editor/plugins/org.fusesource.ide.launcher. Его и надо взять для настройки удалённого дебага студии:
Поставьте брекпоинт, например, в классе org.fusesource.ide.launcher.debug.util.CamelDebugUtils в методе createAndRegisterEndpointBreakpoint. Когда дебаг подцепился к студии можно попробовать открыть в графическом редакторе проект Apache Camel и установить простую точку останова на любом элементе маршрута. Если всё сконфигурировано верно, то выполнение остановится в обозначенной точке - можно начать исследование.
В ходе пошагового дебага выясняется, что в классе org.eclipse.debug.internal.core.BreakpointManager создаётся понятие маркера для последующего сохранение этой информации на диск. Кроме этого, происходит изменение оперативной информации по синхронному событию в дебаггере по умолчанию - org.fusesource.ide.launcher.debug.model.CamelDebugTarget метод breakpointAdded. Маркеры не сохраняются синхронно на диск, а происходит это только при штатном закрытии Eclipse. Файл находится примерно по такому пути:
JBOSSTOOLS_WORKSPACE/.metadata/.plugins/org.eclipse.core.resources/.projects/org.fusesource.ide.launcher/.markers
Часть 2 Тем временем в рантайме
Сразу оговорюсь - текущий блог писался с использованием достаточно старой версии Camel - 2.21.0. В Camel 3+ пошёл максимальный отказ от Java Reflection и, возможно, механизмы будут другие. Причина использования старой версии - JBossTools ещё не адаптированы для работы с Camel 3.
Итак, начнём - сперва давайте запустим Red Hat Fuse в режиме debug следующей командой:
$./fuse debug
Предполагается, что проект с нашим тестовым маршрутом уже импортирован в Red Hat Developer Studio. Я использовал простой тестовый маршрут из примеров самого Camel:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
<camelContext id="simple-cbr-context"
xmlns="http://camel.apache.org/schema/blueprint" xmlns:order="http://fabric8.com/examples/order/v7">
<route id="route1">
<from id="_from1" uri="file:work/cbr/input"/>
<log id="_log1" message="Receiving order ${file:name}"/>
<choice id="_choice1">
<when id="_when1">
<xpath>/order:order/order:customer/order:country = 'UK'</xpath>
<log id="_log2" message="Sending order ${file:name} to the UK"/>
<to id="_to1" uri="file:work/cbr/output/uk"/>
</when>
<when id="_when2">
<xpath>/order:order/order:customer/order:country = 'US'</xpath>
<log id="_log3" message="Sending order ${file:name} to the US"/>
<to id="_to2" uri="file:work/cbr/output/us"/>
</when>
<otherwise id="_otherwise1">
<log id="_log4" message="Sending order ${file:name} to another country"/>
<to id="_to3" uri="file:work/cbr/output/others"/>
</otherwise>
</choice>
<log id="log5" message="Done processing ${file:name}"/>
</route>
</camelContext>
</blueprint>
Следующим шагом мы подключаемся удалённым дебагером к запущенному Red Hat Fuse:
На первой вкладке выбираем наш файл с маршрутом:
Далее определяем параметры JMX:
И параметры JDWP:
После этого можно запускать процесс дебага. Если конфигурация верна, то дебагер подключится к удалённой JVM и покажет список потоков в соответствующей перспективе студии. Теперь можно поставить брекпоинт на графическом элементе маршрута Camel и инициировать выполнение маршрута. Процесс выполнения должен прерваться в точке:
Проверка наличия брекпоинтов происходит через аспекты - AOP. На процессор - класс, который отвечает за непосредственное выполнение компонента в Camel "навешивается" advice, который выполняется до или после компонента - https://github.com/apache/camel/blob/camel-2.21.x/camel-core/src/main/java/org/apache/camel/processor/CamelInternalProcessor.java#L591. Для коммуникаций между Camel и сторонними инструментами служит класс https://github.com/apache/camel/blob/camel-2.21.x/camel-core/src/main/java/org/apache/camel/processor/interceptor/BacklogDebugger.java - в этом классе происходит работа с брекпоинтами - через него идёт их установка и удаление, проверка наличия брекпоинта для узла в процессе выполнения. JBossTools общается с классом BacklogDebugger через JMX - для этого есть отдельный фасад - https://github.com/jbosstools/jbosstools-fuse/blob/jbosstools-4.16.0.Final/editor/plugins/org.fusesource.ide.launcher/src/org/fusesource/ide/launcher/debug/model/CamelDebugFacade.java.
При обнаружении брекпоинта экземпляр класса BacklogDebugger ставит на паузу в 300 секунд дальнейшее выполнение Camel и происходит передача управления в JBossTools путём добавления значения в мапу suspendedBreakpoints. Со своей стороны в JBossTools запущена периодическая проверка содержания этой мапы через JMX https://github.com/jbosstools/jbosstools-fuse/blob/jbosstools-4.16.0.Final/editor/plugins/org.fusesource.ide.launcher/src/org/fusesource/ide/launcher/debug/model/EventDispatchJob.java#L45 и, при обнаружении нового значения, процесс перехватывается и передаётся в https://github.com/jbosstools/jbosstools-fuse/blob/jbosstools-4.16.0.Final/editor/plugins/org.fusesource.ide.launcher/src/org/fusesource/ide/launcher/debug/model/CamelThread.java#L101, где приостанавливается выполнение потока и управление передаётся UI. Передача управления в UI происходит через события.
- 6.2 (12)
- 7.0 (12)
- activiti (14)
- apache camel (6)
- camel (11)
- devcon (6)
- devops (5)
- emdev (9)
- emdev limited (9)
- entaxy (13)
- esb (10)
- fuse (5)
- gartner (7)
- google apps (6)
- jboss (5)
- liferay (143)
- liferay 7.1 (11)
- liferay dxp (11)
- liferay7 (12)
- openshift (8)
- osgi (5)
- redhat (15)
- rest (6)
- wso2 (70)
- wso2 api-m (10)
- wso2 ei (8)
- wso2ei (5)
- wso2esb (7)
- wso2is (8)
- емдев (11)
Сайт использует файлы cookie. Они позволяют узнавать вас и получать информацию о вашем пользовательском опыте. Это нужно, чтобы улучшать сайт. Посещая страницы сайта и предоставляя свои данные, вы позволяете нам предоставлять их сторонним партнерам. Если вы согласны, продолжайте пользоваться сайтом. Если нет – установите специальные настройки в браузере или обратитесь в техподдержку.