-
Notifications
You must be signed in to change notification settings - Fork 0
ZkJsonSerializer ru2
Основной класс, являющийся фабрикой соответствующего Json-конвертера. Также обладает свойствами, используемыми для настроек.
Важно: в данном контексте сериализация означает загрузку из ZooKeeper
в Json-файл, а десериализация - загрузку из Json-файла в ZooKeeper
!
-
public ZooKeeper ZooKeeper { get; set; }
- экземплярorg.apache.zookeeper.ZooKeeper
из библиотеки ZooKeeperNetEx. Предполагается что соединение уже установлено, необходимая аутентификация пройдена. -
public string Root { get; set; } = "/";
- задаёт дополнительное смемещение по дереву относительно первоначальногоchroot
. По умолчанию имеет значение"/"
, соответствующее отсутствию дополнительное смещения. Таким образом, абсолютный путь узла, к которому мы обращаемся, будет/<chroot>/<Root>
, где<chroot>
- первоначальное смещение, определённое в строке соединения, а<Root>
- значение данного свойства.
Важно: при обращении к узлу по крайней мере его родительский узел должен быть задан в ZooKeeper
!
-
public List<ACL> AclList { get; set; } = [new ACL((int)Perms.ALL, Ids.ANYONE_ID_UNSAFE)];
- задаёт правило доступа ко ВСЕМ узлам создаваемого/обновляемого поддерева. По умолчанию установлен полный доступ. -
public ZkAction Action { get; set; } = ZkAction.Replace;
- задаёт способ обновления поддерева.
-
public void Reset();
- устанавливает экземплярZkJsonSerializer
в состояние готовности. Следует вызывать после выполнения сериализации или десериализации при необходимости повторного использования экземпляра. -
public async Task DeleteAsync();
- вспомогательный метод, не относящийся к сериализации или десериализации, но связанный с внутренней реализацией и к тому же полезный. Удаляет поддерево. -
public async Task<bool> RootExists();
- вспомогательный метод, не относящийся к сериализации или десериализации, но связанный с внутренней реализацией и к тому же полезный. Сообщает, присутствует ли вZooKeeper
данные по пути, заданном свойствомRoot
. -
public async Task CreateRoot();
- вспомогательный метод, не относящийся к сериализации или десериализации, но связанный с внутренней реализацией и к тому же полезный. Создаёт вZooKeeper
путь, заданный свойствомRoot
, если он отсутствует. -
public JsonElement IncrementalSerialize(string scriptPrefix);
- считывает дерево с обработкой команд простого встроенного языка, позволяющего повторное использование частей JSON-файла.
<prefix>
назначается исходя из личных предпочтений. Для работы с конкретным префиксом метод IncrementalSerialize(<prefix>)
вызывается с ним в качестве аргумента.
-
<prefix>:base
- название поля, значением которого является абсолютный или относительный путь к объекту, который будем называть базовым, элементы которого будут скопированы в текущий объект (наследник). При этом
- копируются все свойства базового объекта.
- Свойства, содержащиеся как в базовом так и в наследнике, принимают значения, установленные в наследнике.
- Свойства наследника, названия которых начинаются со знака
-
, удаляются.
Также можно добавить свойства, не содержащиеся в базовом объекте. Можно наследовать от нескольких объектов, в этом случае пути к базовым объектам перечисляются в массиве. Важно: все пути, используемые для ссылок на базовые объекты, должны указывать на элементы внутри того же JSON-файла, загруженного в Zookeeper
!
-
<prefix>:value(<path>)
- значение поля или элемент массива, которое заменяется на значение элемента-донора, указанного абсолютным или относительным путём . Вычисление данного значения производится после применения всех команд<prefix>:base
. Ограничения:
- значение элемента-донора должно быть терминальным, то есть не объектом и не массивом.
- Значение элемента-донора не должно содержать команд.
Важно: все элементы-доноры должны находиться внутри того же JSON-файла, загруженного в Zookeeper
!
-
<prefix>:path([from,[count]])
- значение поля или элемент массива, которое заменяется на значение отрезка абсолютного пути к текущему элементу. Границы этого отрезка выбираются с помощью целочисленных параметровfrom
иcount
. Отрицательное значение параметраfrom
является сокращённой записью для отсчёта с конца. -
<prefix>:eval(<arg>)
- значение поля или элемент массива, которое заменяется на строку, полученную после преобразования параметра<arg>
. Строка<arg>
может содержать команды<prefix>:value(<path>)
и<prefix>:path([from,[count]])
, которые будут заменены на вычисленные значения.
Пример работы приведён в Демо:ZkJsonDemo.
ZkJsonSerializer configSerializer = new()
{
...
};
configSerializationOption.Converters.Add(configSerializer);
TConfig Config = JsonSerializer.Deserialize<TConfig>(
configSerializer.IncrementalSerialize("base"),
configDeserializationOption
);
Кроме перечисленного, в классе ZkJsonSerializer
реализованы абстрактные методы родительского класса System.Text.Json.Serialization.JsonConverterFactory
.
ZooKeeper zk;
// Создаётся экземпляр `ZooKeeper`, ожидается соединение с кластером ...
...
// Соединение установлено!
ZkJsonSerializer factory = new()
{
ZooKeeper = zk,
};
JsonSerializerOptions serializerOptions = new()
{
WriteIndented = true, // Пусть будет красиво
};
// Обязательно добавляем наш экземпляр ZkJsonSerializer в список конвертеров!
serializerOptions.Converters.Add(factory);
// Запишем файл в поток:
Stream output;
// Открываем поток как-то
...
// Пишем файл в поток, ZkStub.Instance - просто затычка, serializerOptions - обязательно!
JsonSerializer.Serialize(output, ZkStub.Instance, serializerOptions);
// Или в асинхронном коде:
// await JsonSerializer.SerializeAsync(output, ZkStub.Instance, serializerOptions);
// Получим `System.Text.Json.JsonElement`, чтобы его обходить или десериализовать в другой объект:
// Сначала сбрасываем состояние фабрики
factory.Reset();
JsonElement jsonElement = JsonSerializer.SerializeToElement(ZkStub.Instance, serializerOptions);
JsonSerializerOptions serializerOptions = new();
// Обязательно добавляем наш экземпляр ZkJson в список конвертеров!
serializerOptions.Converters.Add(factory);
// Будем читать файл из потока:
Stream input;
// Открываем поток как-то
...
factory.Action = ZkAction.Replace; // или ZkAction.Update, если обновляем отдельные поля
// Читаем файл из потока, ZkStub - просто тип-затычка, serializerOptions - обязательно!
JsonSerializer.Deserialize<ZkStub>(input, serializerOptions);
// Или в асинхронном коде:
// await JsonSerializer.DeserializeAsync<ZkStub>(options.Reader, serializerOptions);
// Пусть у нас есть объект `System.Text.Json.JsonElement`, в который мы сериализовали другой объект,
// и мы запишем в `ZooKeeper` его:
// Сначала сбрасываем состояние фабрики
factory.Reset();
JsonSerializer.Deserialize<ZkStub>(jsonElement, options);
factory.DeleteAsync().Wait();
// Или в асинхронном коде:
// await factory.DeleteAsync();