Каждый запрос должен иметь время жизни своих результатов, выражаемое в секундах, по истечении которых они будут стёрты с узла СХД во избежание заполнения дискового пространства ненужными данными.
Состояние обработки запроса может быть одним из пяти:- запрос создан, но ещё не передан в обработку серверным компонентом;- запрос передан в обработку серверным компонентом, но никакие результаты ещё не известны;- запрос обрабатывается сервером, известен прогресс (сколько шагов всего в запросе, сколько шагов выполнено и сколько из них - с ошибкой) и могут быть доступны промежуточные результаты (список файлов с результатами, расположенными в директории результатов);- запрос обработан, результаты доступны;- запрос обработан, но результаты недоступны или доступны не полностью в результате ошибки, информация о которой доступна.
Параметры запросов и результатов их выполнения указаны в табл. 3.1.
Формат записи запроса и результатов
В качестве формата записи параметров запроса и результа был выбран синтаксис языка разметки XML [7], как гибкий способ выражения различных структур данных, легко подвергающийся модификации и имеющий множество реализаций, снижающих затраты на разработку сериализации собственных структур данных. Пример задачи копирования файлов, обращённой в документ XML, приведён ниже:
<?xml version=”1.0” encoding=”utf-8”?>
<task>
<parameter name=”task_id” value=”223”/>
<parameter name=”task_type” value=”DOWNLOAD”/>
<parameter name=”creation_date” value=”1303033975”/>
<parameter name=”modification_date” value=”1303036333”/>
<parameter name=”task_expiration” value=”86400”/>
<state>
<parameter name=”name” value=”Running”/>
<parameter name=”total_steps” value=”4”/>
<parameter name=”complete_steps” value=”2”/>
<parameter name=”failed_steps” value=”0”/>
<results>
<result_1>
<parameter name=”node” value=”c001n01”/>
<parameter name=”path” value=”/var/log/messages.log”/>
<parameter name=”size” value=”65821”/>
<parameter name=”is_successful” value=”true”/>
</result_1>
<result_2>
<parameter name=”node” value=”c001n03”/>
<parameter name=”path” value=”/var/log/messages.log”/>
<parameter name=”size” value=”365112”/>
<parameter name=”is_successful” value=”true”/>
</result_2>
</results>
</task>
Параметры запросов протокола
клиент-серверного взаимодействия
Таблица 3.1
|
Тип запроса |
Параметры |
Время жизни |
Метрика прогресса |
Результат |
|
Поиск сообщения в журналах |
From: дата начала периода To: дата окончания периода Nodes: список узлов для поиска LogTypes: список типов просматриваемых журналов Pattern: шаблон для поиска IsRegExp: флаг регулярного выражения в шаблоне |
1 сутки |
Всего: количество узлов, помноженное на 100% Выполнено: сумма долей просмотренных журналов на всех узлах (в процентах) Ошибки: количество неудочно просмотренных журналов |
Список файлов журналов, сохранённых на узле серверного компонента |
|
Генерирование отладочных журналов |
StartDate: дата начала генерирования журнала Nodes: список узлов LogLevel: минимальный уровень важности сообщений Loggers: список компонентов - источников сообщений Filters: список фильтров сообщений |
30 суток |
Всего: количество узлов Выполнено: количество обработанных узлов Ошибки: количество узлов, вернувших ошибку |
Отладочные журналы, сохранённые на генерирующих узлах |
|
Создание журнала сетевых пакетов |
StartDate: дата начала генерирования журнала Nodes: список узлов Nic: сетевой интерфейс для захвата пакетов Filters: список фильтров пакетов |
30 суток |
-//- |
Журналы сетевого трафика, сохранённые на генерирующих узлах |
|
Прерывание задачи генерирования отладочных или сетевых журналов |
TaskId: идентификатор задачи генерирования журналов |
10 минут |
-//- |
Отсутствует |
|
Поиск файлов журналов или конфигурации для копирования |
Nodes: список узлов для поиска DataTypes: список типов искомых данных QueryAllSessions: флаг поиска файлов во всех сессиях |
1 час |
Всего: количество узлов, помноженное на количество типов данных Выполнено: суммарное количество просмотренных типов данных на всех узлах Ошибки: количество неудачно просмотренных типов данных на всех узлах |
Список найденных файлов на узле серверного компонента |
|
Копирование файлов журналов или конфигурации |
DataPaths: список путей к копируемым файлам |
1 сутки |
Всего: количество копируемых файлов Выполнено: количество файлов, начатых копироваться Ошибки: количество нескопированных из-за ошибок файлов |
Указанные файлы на узле серверного компонента |
|
Декодирование содержимого пакета типа SmartPacket |
Data: Base64 - закодированное содержимое пакета |
10 минут |
Всего: количество декодируемых пакетов Выполнено: количество декодированных пакетов Ошибки: количество недекодированных пакетов |
Декодированное содержимое пакета на узле серверного компонента |
|
Остановка серверного компонента |
Без параметров |
10 минут |
Всего: 1 Выполнено: 1 Ошибки: 0 |
Отсутствует |
Поскольку протокол использует одинаковые
сущности (запросы, задачи, результаты, состояния) в обоих компонентах
программного комплекса, то целесообразно разработать общий модуль, занимающийся
сериализацией и десериализацией объектов «запрос» и «задача» в запись на языке
разметки XML. Поскольку взаимодействие по протоколу происходит через файловую
систему, то сериализация и десериализация будет происходить в/из потока
ввода-вывода.
.3 Разработка структуры серверного компонента
Серверный компонент выполняет чётко ограниченный круг задач, что позволяет его представить в виде основных служб, предоставляющих интерфейсы для решения данных задач. Помимо основных служб необходимы ещё контроллер, который будет управлять работой этих служб и дополнительные инфраструктурные службы, обеспечивающие работу основных. Таким образом структура компонента может быть представлена в виде перечня модулей:
контроллер жизнедеятельности серверного компонента - стартует первым и управляет временем жизни всех остальных модулей;
модуль серверной библиотеки - инициализирует использование библиотеки, предоставляет её интерфейс остальным модулям;
библиотека протокола - предоставляет единые средства для маршаллинга экземпляров сущностей в файлы и из файлов
модуль работы с файловой системой - предоставляет работу с состоянием и содержимым директорий, как со списками объектов-потоков ввода или вывода
модуль управления очередью запросов - отслеживает новые запросы, вызывает создание по ним задач у соответствующих фабрик, передаёт задачи модулю очереди задач, очищает очередь запросов от незавершённых запросов;
модуль управления очередью задач - контролирует исполнение задач, помещает их в хранилище результатов и очищает устаревшие результаты; это центральный модуль серверного компонента, координирующий выполнение запросов от клиентского модуля;
модуль управления фабриками задач - предоставляет фабрики задач, регистрирует фабрики в модуле управления очередью запросов.
Компоновка и взаимодействие модулей показано на рис. 3.5. Штриховыми линиями показаны действия по созданию и инициализации модулей, выполняемые главным модулем «Контроллер», сплошными линиями показаны взаимодействия модулей, связанные с обработкой запросов от клиентского модуля.
Контроллер, модуль очереди запросов и модуль очереди задач работают параллельно, поэтому следует рассмотреть их работу по-отдельности.
Контроллер:
Контроллер по своим функциям одинаков для обоих компонентов программного комплекса, поэтому его базовые функциональности, общие для обоих модулей выделены в отдельный модуль; контроллер серверного компонента наследует функциональности общего и добавляет лишь специфичные функции - захват блоикировки и инициализацию модулей компонента.
Таким образом базовая сущность контроллера является абстрактной и предоставляет функции:
Контроля за временем жизни компонента и его модулей
Создания и хранения списка компонентов
Вызова абстрактного метода инициализации списка компонентов
Запуска модулей компонента в порядке их нахождения в списке
Ожидания остановки компонента
Остановки компонента
Остановки модулей компонента в порядке, обратном их нахождению в списке
Специфичный контроллер серверного компонента осуществляет:
Реализацию функции main, создающей экземпляр контроллера и запускающей его
Захват уникального в рамках ОС объекта блокировки, чтобы обеспечить единственность экземпляра серверного компонента в пространстве процессов ОС, при неудачной попытке завершает работу серверного компонента
Модуль очереди запросов работает циклически, каждая итерация которого происходит не чаще 1 раза за заданный интервал времени (5 секунд) и выглядит следующим образом:
Модуль очереди запросов запрашивает у модуля ФС о наличии новых запросов
Модуль ФС проверяет состояние директории с запросами и возвращает статус наличия новых запросов модулю очереди запросов
Если новых запросов нет, то модуль очереди запросов уходит в ожидание до следующей итерации, в противном случае запрашивает у модуля ФС поток ввода нового запроса
Модуль ФС открывает файл с запросом и возвращает модулю очереди запросов поток ввода из файла с запросом
Модуль очереди запросов создаёт новый запрос, используя маршаллер протокола (общий для клиентского и сереврного компонентов) по данным из потока и сообщает модулю ФС о завершении выборки запроса
Модуль ФС закрывает файл и удаляет его из директории запросов
Модуль очереди запросов определяет фабрику задачи из списка зарегистрированных в нём фабрик, соответствующую запросу, и создаёт на ней экземпляр задачи
При создании экземпляра задачи ей передаётся интерфейс модуля ФС и маршаллер протокола (общий для клиентского и серверного компонентов)
Модуль очереди запросов ставит задачу в очередь модуля очереди задач и переходит к следующей итерации
Модуль очереди задач работает циклически, где каждая итерация выглядит следующим образом:
Модуль очереди задач находится в режиме ожидания до появления в очереди новой задачи
Модуль очереди задач запускает выполнение задачи
Задача выполняется, периодически производя сериализацию своего содержимого, используя полученный маршаллер и интерфейс модуля ФС (для получения нового временного потока вывода, который после закрытия будет преобразован в готовый файл со статусом задачи)
После завершения выполнения задачи управление передаётся модулю очереди задач, который добавляет задачу в список выполненных задач
Модуль очереди задач анализирует список выполненных задач и выбирает те, у результатов которых истёк срок хранения и удаляет их из своего списка
Модуль очереди задач передаёт список задач с истёкшим сроком хранения модулю ФС, который их удаляет из директории результатов
Модуль очереди задач переходит к
следующей итерации
Рисунок 3.5 Схема структуры
серверного компонента
.4 Реализация серверного компонента
Для реализации программного комплекса выбраны следующие средства разработки:
Интегрированная среда разработки Eclipse (версия Helios Service Release 2), как отвечающая всем требованиям по разработке программного продукта на языке Java Standard Edition, имеющая множество вспомогательных средств для обеспечения удобного процесса разработки;
Система контроля версий SVN для обеспечения надёжного хранения исходных кодов программного комплекса, а также для возможности удобной синхронизации исходных кодов между несколькими рабочими станциями разработчика;
Рабочие станции программиста, имеющие характеристики не ниже следующего уровня: процессор частотой 2ГГц, объём оперативной памяти 1Гб, объём доступного дискового пространства 1Гб, размер дисплея 17 дюймов, разрешение экрана 1024*768 пикселей;
Операционная система Windows XP SP2 или SP3.
При реализации серверного компонента была произведена декомпозиция задачи, в результате которой внутри каждого модуля получился набор сущностей, реализованных в виде интерфейсов, классов и абстрактных классов. Для краткости изложения приведены только сигнатуры классов (интерфейсов), полный исходный текст программного комплекса приведён в приложении 2.
Модуль контроллера представлен следующими классами:
Класс контроллера серверного компонента, унаследованный от базового контроллера. Имеет статический метод main() - точку входя для запуска серверного компонента.
package server.controllerclass ServerController extends ModulesController {static void main(String[] args)
@Overridevoid initModules() throws ModuleException {void obtainServerLock() throws ModuleException
}
Класс базового абстрактного контроллера компонента - реализует методы запуска и остановки зарегистрированных модулей; управляет временем жизни компонента.
package common.controller;abstract class ModulesController {List<Module> modules = new ArrayList<Module>();void execute()abstract void initModules() throws ModuleExceptionboolean add(Module module)void startModules() throws ModuleExceptionvoid waitForStop()void stop()void stopModules() throws ModuleException
}
Интерфейс модуля, регистрируемого в контроллере и управляемого им.
package common.controller;interface Module {void start() throws ModuleExceptionvoid stop() throws ModuleException
}
Класс исключений, специфицирующий ошибки, произошедшие в коде контроллера.
package common.controller;class ModuleException extends Exception {
public ModuleException(String message)
}
Модуль серверной библиотеки представлен следующими классами:
Класс интерфейса серверной библиотеки - инициализирует список доступных узлов, а также возвращает интерфейс с доступными методами уровня узла.
package server.library;interface ServerLibrary {void initNodes();NodeEnvironment getNodeEnvironment(String nodeName);boolean decodeSmartPacket(byte[] content);
}
Интерфейс с методами, выполняемыми указанным узлом, афктически все метода реализуют функции программного комплекса.
package server.library;interface NodeEnvironment {boolean searchInLogs(Date from, Date to, Collection<LogType> logTypes, String pattern, boolean isRegExp);boolean startCustomLog(String logName, LogLevel level, Collection<String> loggers, Collection<LogFilter> filters);boolean stopCustomLog(String logName);boolean startTcpDumping(String nic, String filters);boolean stopTcpDumping();boolean queryFiles(Collection<DataType> dataTypes, boolean allSessions);boolean downloadFiles(Collection<String> paths);
}
Класс модуля серверной библиотеки, служит только для инициализации серверной библиотеки и хранения инициализированного экземпляра.
package server.modules;class ServerLibraryModule implements Module {
@Overridevoid start() throws ModuleException
@Overridevoid stop() throws ModuleExceptionServerLibrary getLibrary()
}
Модуль ФС представлен следующими классом:
Класс модуля управления файловой система - преимущественно методы по чтению задачи или её записиа.
package server.modules;class FilesystemModule implements Module {
@Overridevoid start() throws ModuleException
@Overridevoid stop() throws ModuleExceptionCollection<String> getRequestsList()InputStream getRequestStream(String request)void removeRequest(String request)void persistTask(Task task) throws IOExceptionvoid removeExpiredTasks(Collection<String> expiredTasks) throws IOException
}
Модуль очереди запросов представлен следующими классами:
Класс процессора запросов, реализует интерфейс Runnable, чтобы выполнять задачу отслеживания поступающих запросов в параллельном потоке.
package server.modules;class RequestProcessingModule implements Module, Runnable {FilesystemModule filesystemModule;JobProcessingModule jobProcessingModule;Thread queueProcessingThread;Map<String, TaskFactory> factories = new HashMap<String, TaskFactory>(); RequestProcessingModule(FilesystemModule filesystemModule, JobProcessingModule jobProcessingModule)
@Overridevoid start() throws ModuleException
@Overridevoid stop() throws ModuleExceptionvoid registerTaskFactory(String type, TaskFactory factory)void unregisterTaskFactory(String type, TaskFactory factory)
@Overridevoid run()
}
Модуль очереди задач представлен следующими классами:
Класс процессора задач, реализует интерфейс Runnable, чтобы осуществлять выполнение поставленных в очередь задач в параллельном потоке.
package server.modules;class JobProcessingModule implements Module, Runnable {FilesystemModule filesystemModule;Thread jobsProcessor;Queue<Task> jobs = new ConcurrentLinkedQueue<Task>();JobProcessingModule(FilesystemModule filesystemModule) {
@Overridevoid start() throws ModuleException {
@Overridevoid stop() throws ModuleException {void createJob(Task request) {
@Overridevoid run() {
}
Модуль фабрик задач представлен следующими классами:
Класс модуля фабрик задач, инициализирует фабрики задач и регистрирует их в классе процессора запросов.
package server.modules;class FactoriesModule implements Module {ServerController serverController;ServerLibraryModule serverLibraryModule;FilesystemModule filesystemModule;RequestProcessingModule requestProcessingModule;Map<String, TaskFactory> factories;FactoriesModule(ServerController serverController, ServerLibraryModule serverLibraryModule, FilesystemModule filesystemModule, RequestProcessingModule requestProcessingModule)
@Overridevoid start() throws ModuleExceptionvoid initializeFactories()
@Overridevoid stop() throws ModuleException
}
4. РАЗРАБОТКА КЛИЕНТСКОГО КОМПОНЕНТА
ПРОГРАММНОГО КОМПЛЕКСА С ГРАФИЧЕСКИМ ИНТЕРФЕЙСОМ ПОЛЬЗОВАТЕЛЯ
.1 Разработка структуры клиентского
компонента
Структура клиентского компонента разделена на три слоя, согласно назначению сущностей, их состявляющих.
Слой «Модель» состоит из сущностей, которыми оперирует программный комплекс (фактически это данные, с которыми он работает); слой «Контроллер» состоит из сущностей, оперирующих сущностями слоя «Модель», и предоставляет набор интерфейсов для всех возможных операций над ними; слой «Вид» состоит из сущностей, реализующих представление сущностей слоя «Модель», а также функциональных возможностей, предоставляемых слоем «Контроллер».
Отдельный модулем является клиентская библиотека, предоставляющая функции управления соединением с узлом СХД Centera, а также отправки/получения данных на/с кластера. Интерфейс и описание функций этой библиотеки приведены ниже: