Теория
WebSphere — крутой сервер приложений, с кучей плюшек, но как IBM старательно все это скрывает от масс любопытных разработчиков сильно удивляет. В этой статье освещается процесс контроля таблиц внутреннего планировщика заданий прямо из кода java-приложения.
На тему развертывания шедулера и основ работы с ним информация в интернете есть. Но одажды мне понадобилось контролировать целостность таблиц прямо из программы. Вот тут и началось веселье. Информацию по этому процессу в интернете я не нашел. Хотя документация конечно есть, но в рамках решения задач администрирования, и приводятся примеры на JACL и Jython языках. Для переноса алгоритма на Java этого явно не достаточно, т.к. подходы немного отличаются.
WebSphere обладает внутренним механизмом планирования задач. И это здорово. Для его работы требуется развернуть в базе таблички шедулера, где он будет хранить свои задачи. Структура этих таблиц достаточно освещена в соответствующих ddl скриптах, поставляющихся вместе с WebSphere'ой(AppServer\Scheduler\*.ddl). Более того, можно даже не заботится об этих табличках и хранить их во внутренней серверной Derby-базе, которая идет вместе с сервером приложений с версии 6.1 в одном комплекте. Как же все-таки контролировать таблицы планировщика задач?
Я решил эту проблему использую классы IBM'овской библиотеки com.ibm.ws.runtime_6.1.0.jar (AppServer\plugins\com.ibm.ws.runtime_6.1.0.jar). Документацию по этим классам я также не нашел, поэтому вооружившись декомпилером начал свой беспощадный анализ.
Практика
Будем считать, что шедулер у нас развернут и мы можем сослаться на него по JNDI пути(например, java:comp/env/scheduler/ReportScheduler):
Context initialContext = null; Scheduler scheduler = null; try{ initialContext = new InitialContext(); scheduler = (Scheduler) initialContext.lookup(SCHEDULER_JNDI_NAME); } catch (NamingException e) { throw new SchedulerException("Ошибка инициализации: " + e.getMessage(), e); } finally { if (initialContext != null) { try { initialContext.close(); } catch (NamingException e) { logger.log(Level.SEVERE, e.getMessage(), e); } } }
Класс, который реализует логику управления таблицами шедулера — WASSchedulerCfgHelper, реализует интерфейс SchedulerConfigHelper. Основные функции, которые нам нужны:
Проверка наличия таблиц:
public void verifyTables(SchedulerConfiguration paramSchedulerConfiguration)
throws SchedulerDataStoreException;
Создание таблиц:
public Boolean createTables(SchedulerConfiguration paramSchedulerConfiguration)
throws SchedulerDataStoreException;
Удаление таблиц:
public Boolean dropTables(SchedulerConfiguration paramSchedulerConfiguration)
throws SchedulerDataStoreException;
Создаем экземпляр помощника конфигурирования шедулера:
SchedulerConfigHelper schedulerHelper = new WASSchedulerCfgHelper(SchedulerConfigServiceImpl.getInstance());
Как видно SchedulerConfigHelper в конструкторе принимает обязательный аргумент — SchedulerConfigService. С его помощью Helper получает доступ к ресурсам WebSphere и к локальным переменным, но в данной реализации этот объект, грубо говоря, представляет собой заглушку и не влияет на процесс работы с таблицами.
Итак, получаем параметры нашего шедулера — информацию, по которым helper сможет найти нужный шедулер.
SchedulerConfiguration schedulerConfig = scheduler.getSchedulerConfiguration();
Ну а дальше все просто:
if (schedulerHelper.createTables(schedulerConfig)) { // Таблицы для шедулера созданы! doSomething(); }
Стоит учитывать, что если таблицы уже созданы, то метод лишь оставит соответствующее сообщение в логах и завершится, вернув false. Метод verifyTables не возращает никакого значения, а в случае отсутствия нужных таблиц выкидывает SchedulerDataStoreException.
К слову говоря, конечно, можно создавать таблицы с помощью ddl скриптов. Именно так раньше я и делал, но в WebSphere API есть механизмы, которые позволяют нам абстрагироваться от таких тонкостей, как наименование ddl скрипта, пути, создания соединения и т.д. Именно такой подход используется внутри административной консоли сервера.
Используемый java-декомпилятор: Java Decompiler
Спасибо за внимание!