Материал: Разработка программного комплекса для анализа состояния системы хранения данных EMC Centera

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Слой «Модель»

Слой состоит из следующих основных модулей: модуль хранилища настроек, модуль контекста соединения с СХД Centera, модуль контекста клиент-серверной сессии. Кроме того в слое используетя общий для серверного и клиентского компонентов модуль протокола.

Модуль хранилища настроек

Выполняет функции сериализации/десериализации настроек клиентского модуля в/из файлов, находящихся в «рабочей» директории клиентского компонента. «Рабочей» называется директория, в которой находится исполняемый файл клиентской программы. Настройки легко отображаются на документ формата XML, при маршаллинге настроек используется DOM-реализация XML-документа, поставляемая вместе с пакетом Java Runtime Environment 6.0 [8].

Модуль контекста соединения с СХД Centera

Модуль представлен набором сущностей, хранящих в себе свойства соединения с кластером. В частности сущность контекста соединения содержит в себе сущность параметров текущего соединения (адрес узла СХД, название соединения, используемая при установлении соединения учётная запись), пароль для установления соединения, состояние соединения (установлено, не установлено, прервано), версию ПО СХД Centera, контекст текущей клиент-серверной сессии, список узлов СХД Centera c указанием их ролей).

Модуль контекста клиент-серверной сессии

Содержит набор сущностей, связанных с контекстом клиент-серверного взаимодействия: контекст клиент-серверной сессии и их хранилище; сущность хранилища задач и их результатов, созданных в контексте сессии.

Контекст клиент-серверной сессии содержит такой важный атрибут, как объект блокировки сессии, похволяющий работать с сессией только одному экземпляру клиентского компонента. Следует отметить, что понятие сессии присутствует только в клиентском компоненте, поскольку только на клиентской стороне возможен параллельный запуск нескольких копий компонента, серверный компонент всегда проверяет свою уникальность в пространстве запущенных процессов и обрабатывает задачи клиентского компонента независимо от идентификатора сессии.

Общий модуль протокола

Содержит сущности задач вместе со всеми их типами, результатов выполнения, а также сущностей-обёрток над документом XML. Модуль повторно используется в клиентском и серверном компонентах.

Общий модуль типовых задач

Часть модуля протокола - содержит реализацию для всех поддерживаемых типов задач.

Слой «Контроллер»

Слой состоит из трёх модулей - контроллеров клиентского компонента, соединения и задач.

Модуль контроллера клиентского компонента предназначен для управления временем жизни клиентского компонента и реализован по тому же принципу, что и контроллер для серверного компонента (см. подразд. 3.3 пп. 1). Из специфичных для контроллера клиентского компонента функций реализуется только инициализация компонентов.

Модуль контроллера соединения предназначен для управления соединением с узлом СХД Centera, а также для мониторинга состояния соединения и уведомления других сущностей об его изменения.

Модуль контроллера задач выполняет наибольшую часть функций по управлению задачами во время всего периода её существования на стороне клиентского компонента.

Модуль контроллера соединения

Состоит из следующих сущностей:

контроллер соединения - предоставляет интерфейс для создания и завершения соединения, отслеживания его состояния (через подписку на уведомления об изменении состояния), получения его параметров (сущность контекст соединения); предоставляет соединение для посылки через него задач серверному компоненту и получения результатов выполнения задачи; использует клиентскую библиотеку для работы с узлом кластера; контролирует работу монитора соединения; отдельно стоящей задачей контроллера является загрузка серверного компонента на узел СХД Centera, если на узле он отсутствует или копия имеет устаревшую версию;

монитор соединения - осуществляет периодический опрос состояния соединения и оповещает всех подписчиков о его изменении;

интерфейс подписчика - реализуется всеми сущностями, которым требуется знать об изменении состояния соединения

Модуль контроллера задач

Выполняет всю логику функций клиентского компонента по работе с задачами, созданными пользователем. Состоит из следующих сущностей:

контроллер задач - предоставляет интерфейс для получения фабрики задач, получения информации об уже созданных задачах, подписки на обновления состояния задач; координирует работу всех остальных сущностей модуля;

интерфейс фабрики задач - содержит методы для создания конкретных типовых задач;

временное хранилище задач - хранит состояние и параметры актуальных задач без сохранения их на файловую систему; в отличие от хранилища задач слоя «Модель» (см п. 4.1.1 пп. 3) используется в текущей работе с задачами, то есть все пользователи модуля контроллера задач работают именно с копией задачи во временном хранилище; это позволяет производить обновление постоянной копии задачи и её результатов незаметно для клиентов модуля и производить быстрое переключение содержимого задачи при его обновлении;

монитор состояния задач - отслеживает изменение состояния задач в очереди задач серверного компонента (см. п. 3.3 пп 3), при обнаружении изменения нотифицирует сущность актуализатора задач об изменении состояния задачи;

актуализатор задач - при получении нотификации об изменении состояния задачи запрашивает обновление состояния задачи (используя клиентскую библиотеку) и обновляет задачу и результаты в хранилище задач (см п. 4.1.1 пп. 3); вычисляет изменения в содержимом задачи, обновляет рабочую копию задачи во временном хранилище и уведомляет подписчиков об обнаруженных изменениях в задаче;

интерфейс подписчика на уведомления об изменении состояния задачи - реализуется всеми сущностями, которым требуется отслеживать изменения состояния задачи.

Слой «Вид»

Слой состоит из модулей графического интерфейса пользователя: модуль основного окна, модуль меню и модули окон, создаваемых по запросам из меню.

Взаимодействие и назначение всех сущностей данного слоя подробно рассмотрено и описано в подразд. 2.3, поэтому рассмотрение состава этих модулей смысла не имеет.

.2 Реализация слоя «Модель» клиентского компонента

Как и в описании реализации серверного компонента для краткости изложения приведены только сигнатуры классов (интерфейсов), полный исходный текст программного комплекса приведён в приложении 2.

Модуль хранилища настроек представлен следующими классами:

Класс предоставляет статические методы для получения настроек в виде обёртки над XML-документом, а также для сохранения этих настроек в хранилище. Каждый экземпляр документа с настройками доступен по своему имени (файла).

package client.model;class RepositoryUtils {final static String REPOSITORY_PATH_ENVIRONMENT_VARIABLE = "sustaining.suite.repository.path";static final String REPOSITORY_SUFFIX = ".repository.xml";static final String REPOSITORY_TAG = "repository";static String sRepositoryDirectoryPath;static Map<String, Params> sRepositories = new HashMap<String, Params>();synchronized static String getRepositoryDirectoryPath()static Params getRepository(String repositoryName)static Params loadRepositoryFromFile(String repositoryName)static void persistRepository(String repositoryName, Params newRepositoryContent)

}

Класс предоставляет методы для доступа к настройкам клиента в объектном виде, в том числе производит преобразование настроек клиентского компонента из объектного вида в древовидный вид документа XML и обратно.

package client.model;class ClientContext {static final String CONNECTIONS_REPOSITORY = "clusters.connections";static final String CONNECTION_TAG = "connection";static final String CONNECTION_NAME = "name";static final String CONNECTION_ADDRESS = "address";static final String CONNECTION_LOGIN = "login";static Map<String, ConnectionParams> connectionsParams = null;static Map<String, ConnectionParams> getConnectionsParams()static boolean updateConnectionsParams(ConnectionParams existingConnectionParams, ConnectionParams newConnectionParams) throws ClientContextException

private static void persistConnectionsParams()

}

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

package client.model;class ClientContextException extends Exception {ClientContextException(String message)

}

Модуль контекста соединения с СХД Centera представлен следующими классами:

Класс контекста соединения, по своей сути является объектом - хранилищем свойств, относящихся к текущему состоянию соединения с серверным компонентом (методы установки и получения значений полей опущены).

package client.model;class ConnectionContext {enum State {(false),(true),(false);final boolean isConnected;State(boolean isConnected)boolean isConnected()

};ConnectionParams connectionParams;String password;State state;String centrastarVersion;SessionContext sessionContext;Collection<Node> nodes;

...

Класс параметров соединения с кластером.

package client.model;class ConnectionParams {

private String connectionName;

private String address;

private String login;

public ConnectionParams(String connectionName, String clusterAddress, String login)String getConnectionName()

public String getAddress()

public String getLogin()

@Override

public String toString()

}

Модуль контекста клиент-серверной сессии представлен следующими классами:

Класс хранилища сессий, предоставляет интерфейс для создания новой сессии.

package client.model;class SessionsRepository {static SessionContext createSession()

}

Класс контекста сессии. Как и класс контекста соединения, по существу является хранилищем настроек и параметров текущего состояния клиент-серверной сессии. Для краткости методы установки и получения полей класса опущены.client.model;

public class SessionContext {Object sessionLock;int sessionId;int creationTimestamp;int lastUpdateTimestamp;long size;Map<Integer, Task> tasks;

...

Интерфейс хранилища задач. Предоставляет базовые методы для работы с задачами.

package client.model;interface TaskRepository {int createTask(Task task);Task getTask(int id);void removeTask(int id);

}

Класс хранилища задач, хранимого на диске. В качестве параметра конструктору передаётся директория сессии, в которой нужно создать хранилище задач (с результатами).

package client.model;class PersistedTaskRepository implements TaskRepository {PersistedTaskRepository(File directory)

@Overrideint createTask(Task task)

@OverrideTask getTask(int id)

@Overridevoid removeTask(int id)

}

Общий модуль работы с обёрткой XML представлен следующими классами:

Интерфейс для работы с объектной моделью набора параметров вместо древовидной XML.

package common.params;interface Params {void setName(String name);String getString(String name) throws ParamsException;void putString(String name, String value);void putParams(String name, Params params);Params[] getAllParamsWithName(String name);

Element getXmlContent();

}

Реализация интерфейса объектных параметров.

package common.params;class ParamsImpl implements Params {static final String PARAMETERS_ROOT = "parameters";static final String PARAMETER = "parameter";static final String PARAMETER_NAME = "name";static final String PARAMETER_VALUE = "value";Document document;Element root;ParamsImpl(Node node)ParamsImpl()ParamsImpl(Params params)

@Overridevoid setName(String name)

@OverrideString getString(String name) throws ParamsException

@Overridevoid putString(String name, String value)

@Overridevoid putParams(String name, Params params)

@OverrideParams[] getAllParamsWithName(String name)

@Overridefinal Element getXmlContent()

@OverrideString toString()

}

Класс исключения, возбуждаемого в случаях возникновения ошибки при работе с сущностью Params.common.params;class ParamsException extends Exception {ParamsException(String message)

}

Общий модуль протокола представлен следующими классами:

Интерфейс задачи. Это класс вобрал в себя не только общие для всех задач параметры, но и такие члены класса, как перечислимый тип State (состояние задачи) и класс результата выполнения задачи.

package common.protocol;interface Task {void setId(int id);int getId();void setType(String type);String getType();void setCreationTime(Date creationDate);Date getCreationTime();void setModificationTime(Date modificationDate);Date getModificationTime();void setExpirationPeriod(int expirationPeriod);int getExpirationPeriod();void setState(State state);State getState();void setResults(Collection<Result> results);Collection<Result> getResults();Params getParams();interface State {enum Name { Pending, Initial, Running, Complete, Aborted };void setName(Name name);Name getName();void setTotalSteps(int totalSteps);int getTotalSteps();void setCompleteSteps(int completeSteps);int getCompleteSteps();void setFailedSteps(int failedSteps);int getFailedSteps();

}interface Result {void setId(int id);int getId();void setNode(String node);String getNode();void setPath(String path);String getPath();void setSize(long size);long getSize();void setSuccessful(boolean isSuccessful);

public boolean isSuccessful();

}

}

Класс реализации интерфеса обёртки, методы установки и получения значений полей класса опущены для краткости.

package common.protocol;class TaskImpl implements Task {int id;String type;Date creationTime;Date modificationTime;int expirationPeriod;State state;Collection<Result> results;Params params;TaskImpl()TaskImpl(Params params)

...

Класс маршиллинга задач из файла (потока) с XML и обратно

package common.protocol;class Marshaller {Task unmarshal(InputStream inputStream) throws MarshallerExceptionvoid marshal(Task task, OutputStream outputStream) throws MarshallerException

}common.protocol;class MarshallerException extends Exception {MarshallerException(String message)

}

Модуль типовых задач представлен следующими классами. Все нижепереисленные типовые задачи являются по своей сути контейнерами для параметров своей работы, поэтому перечисление методов установки и получения опущены за своей тривиальностю

package common.protocol.tasks;class SearchInLogTask extends TaskImpl {Date from;Date to;Set<String> nodes;Set<LogType> logTypes; boolean isPatternRegExp;String pattern;final static String TYPE = "SEARCH_IN_LOG";

...common.protocol.tasks;class CustomLoggingTask extends TaskImpl {Date startDate;Set<String> nodes;LogLevel level;Set<String> loggers;Collection<LogFilter> filters;final static String TYPE = "CUSTOM_LOGGING";

...common.protocol.tasks;class TcpDumpingTask extends TaskImpl {Date startDate;Set<String> nodes;Nic nic;String filter;final static String TYPE = "TCP_DUMPING";enum Nic { eth0, eth1, eth2 }

...common.protocol.tasks;class AbortTask extends TaskImpl {int abortedTaskId;final static String TYPE = "ABORT";

...common.protocol.tasks;class QueryDataTask extends TaskImpl {Set<String> nodes;Set<String> dataTypes; boolean queryForeignSessions;final static String TYPE = "QUERY_DATA";

...common.protocol.tasks;class DownloadTask extends TaskImpl {Map<String, Collection<String>> paths;final static String TYPE = "DOWNLOAD";

...common.protocol.tasks;class SmartPacketDecodeTask extends TaskImpl {String encodedPacketContent;final static String TYPE = "SMART_PACKET_DECODE";

...common.protocol.tasks;class StopServerTask extends TaskImpl {final static String TYPE = "STOP_SERVER";

...common.protocol.tasks;class Log {enum Level { Debug, Verbose, Status, Warning, Error };enum FilterType { Message };class Filter {FilterType type;String value;Filter(FilterType type, String value)void setType(FilterType type)FilterType getType()void setValue(String value)

public String getValue()

}

}

.3 Реализация слоя «Контроллер» клиентского компонента

Как и в описании реализации серверного компонента для краткости изложения приведены только сигнатуры классов (интерфейсов) c константами, полный исходный текст программного комплекса приведён в приложении 2.

Модуль контроллера соединения представлен следующими классами:

Класс контроллера клиентского компонента. Благодаря наличию статического метода main имеет точку входа для запуска клиентского компонента. Инициирует список модулей компонента и через базовый класс их запускает, впоследствие при заврешении работы компонента - останавливает..

package client.controller;class ClientController extends ModulesController {static void main(String[] args)

@Overridevoid initModules() throws ModuleException

}

Класс контроллера соединений. Предоставляет интерфейс для отслеживания состояния соединения с сервером, установки и завершения соедниения. Производит подписку на обновления статуса соединения.client.controller;class ConnectionController {

private ConnectionMonitor connectionMonitor;void registerHandler(ConnectionUpdateHandler handler)void unregisterHandler(ConnectionUpdateHandler handler)ConnectionContext establishConnection(ConnectionParams connectionParams)void disconnect(ConnectionContext connection)

}

Класс мониторинга соединения, реализует интерфейс Runnable для выполнения в параллельном потоке задачи мониторинга состояния соединения с узлом СХД Centera. При изменении состояния оповещает подписчиков (подписка происходит через контроллер соединения).

package client.controller;class ConnectionMonitor implements Runnable {Collection<ConnectionUpdateHandler> handlers;ConnectionMonitor()void registerHandler(ConnectionUpdateHandler handler)void unregisterHandler(ConnectionUpdateHandler handler)

@Overridevoid run()

}

Интерфейс, реализуемый подписчиком на обновления состояния соединения с узлом СХД.

package client.controller;interface ConnectionUpdateHandler {void handle(ConnectionContext context);

}

Модуль контроллера задач представлен следующими классами:

Класс контроллера задач. Реализует интерфейс подписчика на обновления о состоянии соединения с кластером, чтобы управлять процессами отслеживания изменений состояния текущих задач и созданием новых задач в зависимости от состояния соединения. Предоставляет интерфейс для получения фабрики, создающей новые задачи. Подписывает сторонние процессы на обновления о состоянии задач, реально подписка осуществляется у актуализатора задач.