Библиотеки разработки

Для настройки логики работы с данными в Платформе реализован раздел Схемы обработки. Здесь вы можете создать, изменить или удалить следующие схемы обработки данных:

Настройка схемы обработки данных заключается в заполнении основных параметров, установке переменных, создании схемы процесса или добавлении кода логики работы.

Сообщения и их свойства

Тип Сообщение

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

Предусловие: создана в процессе переменная типа Сообщение с именем ВхСообщ.

Свойства типа:

  • Id - string;

  • CorrelationId - string;

  • CreationDate - DateTime (utc);

  • Properties;

  • IsArray - является ли тело сообщения массивом;

  • OriginalSystemDataType (string, get-only);

  • StreamId (Guid, get-only) - идентификатор цепочки запросов;

  • BodyLength (int, get-only) - размер тела сообщения в байтах;

  • HasBinaryInQueue (bool, get-only) - есть ли бинарные данные в очереди;

  • IsBinaryLoadedOrSet (bool, get-only) - загружены ли бинарные данные;

  • IsNewBinary (bool, get-only) - бинарные данные были установлены пользователем.

DataType

Guid GetDataTypeId()
bool HasDataType()
void SetDataTypeId(Guid value)
bool TrySetDataTypeId(Guid value)

//генерируемые

Types.DataTypes GetDataType() - возвращает значение Types.DataTypes в соответствии с
DataType сообщения.
если DataType, указанного в сообщении, нет или он не заполнен, то возвращает
Types.DataTypes.Empty
bool SetDataType(Types.DataTypes value) - устанавливает в DataType значение в соответствии
с value.
если value = 0, то очищает DataType и возвращает true. Если такого DataType нет, то
возвращает false
Types.Classifiers GetClassifier() - возвращает enum, соответствующий полю dataTypeId из
конфигурации классификатора.

SystemDataType

Guid GetSystemDataTypeId()
bool HasSystemDataType()
void SetSystemDataTypeId(Guid value)
bool TrySetSystemDataTypeId(Guid value)

//генерируемые

Types.SM GetSystemDataType() - возвращает значение Types.SM в соответствии с
SystemDataType сообщения.
если SystemDataType, указанного в сообщении, нет или он не заполнен, то возвращает
Types.SM.Empty
bool SetSystemDataType(Types.SM value) - устанавливает в SystemDataType значение в
соответствии с value.
если value = 0, то очищает SystemDataType и возвращает true. Если такого SystemDataType
нет, то возвращает false

Source

Guid GetSourceId()

//генерируемые

Cluster.Systems GetSource() - возвращает систему из поля Source.
Если Source - не система, то возвращает Cluster.Systems.Empty

Receivers

OwnList<Module> GetReceiversList()
void SetReceivers(OwnList<Module> receivers)
void AddReceiver(Guid receiver)
void RemoveReceiver(Guid id)

//генерируемые

OwnList<Cluster.Systems> GetReceivers() - перебирает получателей и возвращает только
получателей-систем
bool AddReceiver(Cluster.Systems system) - добавляет в список получателя.
Если такой получатель уже есть - возвращает true.
Если такого получателя нет или system==0, то ничего не делает и возвращает false
bool AddReceivers(OwnList<Cluster.Systems> systems) - добавляет в список получателей.
Если хотя бы одного получателя нет или system==0, то ничего не делает и возвращает false.
Если есть дубликаты - второй раз не добавляем.
bool RemoveReceiver(Systems system) - удаляет получателя.
Если такого получателя нет в списке в сообщении, то возвращает true.
Если system не существует или system==0, то возвращает false
bool ClearReceivers() - очищает всех получателей

Обработчики

Для получения сведений об обработчике сообщения используется метод:

Metadata.Handlers GetHandler()

Body

Преобразования тела сообщения в маппинге и алгоритме

Неявные преобразования Сообщение.Body (при использовании маппинга без выражений) в: - String (Массив = false) - неявно вызывается метод GetBodyAsString(); - Тип данных, Сложный тип - неявно вызывается метод GetBodyAsObject(). Явные преобразования «Сообщение» в Тип данных:

byte[] GetBodyAsBytes() //получить тело сообщения как массив байт
string ВхСообщ.GetBodyAsString() // получить тело в типе строка
JObject ВхСообщ.GetBodyAsObject() // получить тело сообщения как объект
// если в теле передан массив из одного элемента вернет этот элемент как объект типа
object ВхСообщ.GetBodyAsObject(Type t) // получить тело сообщения как объект
// если в теле передан массив из одного элемента вернет этот элемент как объект типа
T ВхСообщ.CastToDataType<T>() //получить тело сообщения как объект типа.
// если в теле передан массив из одного элемента вернет этот элемент как объект типа
T ВхСообщ.CastToDataType<T>(int index) //получить тело сообщения как объект типа.
// если в теле передан не массив и index == 0 вернет этот элемент как объект типа
// если в теле передан массив и index < длины массива вер нет элемент по индексу как
объект типа
BaseClass ВхСообщ.GetBodyAsDataType() //получить сообщение как объект типа
установленного в DataType
//Если DataType не задан - вернет null
BaseClass ВхСообщ.GetBodyAsSystemDataType() //получить сообщение как объект типа
установленного в SystemDataType
//Если SystemDataTypeне задан - вернет null

Примеры использования в алгоритме

// Тип - Тип данных
Тип Тип1 = new Тип();
Тип1 = (Тип)ВхСообщ.GetBodyAsObject(typeof(Тип));
43
Тип Тип2 = new Тип();
Тип2 = ВхСообщ.CastToDataType<Тип>();
Тип Тип3 = new Тип();
Тип3 = ВхСообщ.GetBodyAsObject().ToObject<Тип>();
Тип Тип4 = new Тип();
Тип4 = ВхСообщ.CastToDataType<Тип>(3);
BaseClass body = Вх.GetBodyAsDataType();
switch(body)
{
case Человек par:
Logger.Debug(par.Имя);
break;
case Адрес par:
Logger.Debug(par.Город);
break;
case null:
Logger.Debug("Это нулл");
break;
default:
break;
}

Другие методы

ВхСообщ.SetBody(object value) // задать тело как объект
ВхСообщ.SetBody(string obj) // задать тело сообщения из строки
void CopyBody(Message other) // позволяет скопировать тело из одного сообщения в другое
Копирование полное
bool ВхСообщ.HasBody(); // вернет false, если тело сообщения пустое или длина = 0 байт
bool ВхСообщ.SetBody(Message message) - Копирует тело сообщения, DataType и
SystemDataType

Работа с массивами в теле сообщения

JArray ВхСообщ.GetBodyAsArrayOfObjects(); // возвращает массив Объектов. Работает даже если в теле один объект
int ВхСообщ.BodyArrayCount(); // возвращает количество элементов в массиве, иначе -1
bool ВхСообщ.BodyIsArray(); // проверяет есть ли внутри массив
void ВхСообщ.GetBodyAsArrayOfObjects<T>(OwnList<T> list); //заполняет переданный массив данными из тела
OwnList<BaseClass> ВхСообщ.GetBodyAsArrayOfDataTypes() //получить сообщение как массив объектов типа установленного в DataType
//Если DataType не задан - вернет null
OwnList<BaseClass> ВхСообщ.GetBodyAsArrayOfSystemDataTypes() //получить сообщение как массив объектов типа установленного в SystemDataType
//Если SystemDataType не задан - вернет null

Properties

Сообщение может содержать пользовательские и системные свойства. Для работы с системными свойствами рекомендуется использовать перечисление MessageProperties со значениями:

  • OriginalFileName;

  • AnswerDataType;

  • AnswerSystemDataType;

  • AnswerRequired;

  • MethodType;

  • HandlerId;

  • ResponseCode (поддерживаемые значения: 400-499);

  • ResponseMessage;

  • MessageType24;

  • IsTracking;

  • Format;

  • Trigger.

Поддерживаемые типы свойств:

  • int;

  • string;

  • decimal;

  • bool;

  • Guid;

  • DateTime.

Важно

Во все методы вместо string name можно передавать значение перечисления.

//добавить свойство если такого нет
void AddProperty<T>(string name, T value)
void AddListProperty<T>(string name, OwnList<T> value)
void AddIntProperty(string name, int value)
void AddIntProperty(string name, int? value)
void AddIntListProperty(string name, OwnList<int?> value)
void AddIntListProperty(string name, OwnList<int> value)
// Установка значений
void SetProperty<T>(string name, T value)
void SetListProperty<T>(string name, OwnList<T> value)
void SetIntProperty(string name, int? value)
void SetIntProperty(string name, int value)
void SetIntListProperty(string name, OwnList<int?> value)
void SetIntListProperty(string name, OwnList<int> value)
//получение свойств
T GetProperty<T>(string name)
bool TryGetProperty<T>(string name, out T value)
bool TryGetProperty<T>(string name, out T value, T ifNullDefault)
OwnList<T> GetListProperty<T>(string name)
bool TryGetListProperty<T>(string name, out OwnList<T> values)
int GetIntProperty(string name)
int GetIntProperty(string name, int defaultIfNull)
int? GetIntOrNullProperty(string name)
bool TryGetIntProperty(string name, out int value)
bool TryGetIntProperty(string name, out int? value, int defaultIfNull) => TryGetProperty(name,
out value, defaultIfNull);
bool TryGetIntOrNullProperty(string name, out int? value) => TryGetProperty(name, out value);
OwnList<int> GetIntListProperty(string name)
OwnList<int?> GetIntOrNullListProperty(string name)
bool TryGetIntListProperty(string name, out OwnList<int> value)
bool TryGetIntOrNullListProperty(string name, out OwnList<int?> value)
//прочие методы
Type GetPropertyType(string name)
bool HasProperty(string name)
bool HasProperty<T>(string name)
bool HasListProperty<T>(string name)
bool IsNullProperty(string name)
bool HasIntProperty(string name);
bool HasIntNullProperty(string name);
bool HasIntListProperty(string name);
//Удаление свойств
Remove(string name) //удаляет свойство из коллекции*

Добавлены новые свойства сообщения, которые доступны из шагов процесса. При кодогенерации в маппинге и параметрах шагов проверяется наличие указанных переменных:

InitSource
InitProperties
InitDataType
InitExternalType

Пример:

В шаге Установка переменных есть возможность выполнять маппинг следующего типа:

  • из сообщения в переменную тип «метаданные- типы данных» с настройками маппинга «InitDataType»

  • из сообщения в переменную тип «метаданные- системы» с настройками маппинга «InitSource»

  • из сообщения в переменную тип «метаданные- Метаданные систем» с настройками маппинга «InitExternalType»

  • из сообщения в переменную тип «метаданные- Коллекция свойств» с настройками маппинга «InitProperties»

Логирование

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

Для записи в лог реализован фасад Logger. Методы для записи в лог:

  • Verbose (string textMessage)

  • Debug (string textMessage)

  • Info (string textMessage)

  • Warning (string textMessage)

  • Error (string textMessage)

  • Fatal (string textMessage)

Переданный текст регистрируется в лог того модуля, в котором непосредственно исполняется код. Для лога устанавливается функциональность Custom.

Чтение данных журналов доступно программно только в шаге Сервисный алгоритм в процессах с помощью фасада Logger. Исполнение кода сервисного алгоритма выполняется непосредственно на сервере и только с журналами, размещенными на этом сервере.

Методы фасада Logger

//Оперативные журналы
MessageLoggingEventCollection GetOperativeJournal(Guid moduleId, OperativeJournalFilter
filter);
MessageLoggingEventCollection GetOperativeJournal(Guid moduleId,
                long? minId,
                long? maxId,
                int count = 100,
                DatereonLogLevel level = DatereonLogLevel.Verbose,
                string[] features = null,
                string[] loggerName = null);

//Оперативные события*
MessageEventCollection GetOperativeEvents(Guid moduleId, EventsFilter filter);
MessageEventCollection GetOperativeEvents(Guid moduleId,
                long? minId,
                long? maxId,
                DateTime? start,
                DateTime? end,
                Guid? messageId,
                Guid? processId,
                Guid? streamId,
                Guid? initialSourceId,
                Guid? dataTypeId,
                MessageEventType[] eventTypes,
                string[] operations,
                int count = 100,
                IssueLevel level = IssueLevel.Verbose);

//Архивные журналы
List<HistoryLoggingEvent> GetHistoryJournal(Guid moduleId, HistoryLogFilter filter);
List<HistoryLoggingEvent> GetHistoryJournal(Guid moduleId,
                DateTime? start,
                DateTime? end,
                string queryText,
                DatereonLogLevel Level = DatereonLogLevel.Debug,
                int count = 200,
                string[] features = null,
                string[] loggerNames = null);

//Архивные события
List<HistoryEvent> GetHistoryEvents(Guid moduleId, EventsFilter filter);
List<HistoryEvent> GetHistoryEvents(Guid moduleId,
                DateTime? start,
                DateTime? end,
                Guid? messageId,
                Guid? processId,
                Guid? streamId,
                Guid? initialSourceId,
                Guid? dataTypeId,
                string level,
                string queryText,
                MessageEventType[] eventTypes,
                string[] operations,
                int count = 200);

Для работы с методами реализованы вспомогательные классы:

OperativeJournalFilter - параметры фильтрации данных оперативного журнала

public long MinId = -1;
public long MaxId = -1;
public int Count = 100;
public DatereonLogLevel Level = DatereonLogLevel.Debug;
public string[] Features
public string[] LoggerNames

HistoryLogFilter - параметры фильтрации данных архивного журнала

public DateTime Start
public DateTime End
public int PageSize = 200;
public string Logger
public bool OrderAsc
public string[] LoggersNames

/// Набор логгеров для поиска*
public string[] PositiveLoggersNames;

/// Набор логгеров для исключения*
public string[] NegativeLoggersNames;
public string QueryText
public DatereonLogLevel MinLogLevel
public LoggingFeature[] Features
private string[] _featuresAsString;
public HashSet<LoggingFeature> FeatureInclude ;
public HashSet<LoggingFeature> FeatureExclude ;
public string[] FeaturesAsString

EventsFilter - параметры фильтрации событий

public DateTime Start
public DateTime End
public int PageSize = 200;
public Guid? DataTypeId
public Guid? MessageId
public Guid? ProcessId
public Guid? StreamId
public Guid? InitialSourceId
public IssueLevel IssueLevel
public MessageEventType[] EventTypes
public string[] MessageTypes
public long? MaxId
public long? MinId
public string MinLevel
public string QueryText
public bool OrderAsc
public bool OperativeOnly

HistoryLoggingEvent - запись журнала

public DatereonLogLevel Level

/// Временная метка
public DateTime TimeStamp

/// Фича
public LoggingFeature Feature

/// Имя логера-источника
public string LoggerName

/// Событие
public string Message

/// Номер события
public long EventNumber

HistoryEvent - событие

public DateTime TimeStamp

/// Порядковый номер события
public long EventNumber

/// Тип события
public MessageEventType EventType

/// Имя источника события

public string EventSource

/// Дополнительные сведения о событии
public string EventDetails

/// Копия сообщения (без тела)
public InternalMessage Message

/// Размер тела сообщения

public int MessageBodyLength
public IssueLevel LogLevel

/// ИД модуля, по инициативе которого произошло событие
public Guid TargetId

MessageLoggingEventCollection - набор записей журнала

/// Ключ = идентификатору запущенного процесса
public int Key

/// Список событий логирования
public List<MessageLoggingEvent> Events;
public int? ServiceState
public string ServiceStateMessage

MessageEventCollection - набор событий

/// Ключ = идентификатору запущенного процесса
public int Key

/// Список событий логирования
public List<MessageEvent> Events;
public int? ServiceState
public string ServiceStateMessage

Более подробная информация о настройке логирования и разделения логов по функциональности находится в разделе Настройка уровней логирования.

Работа со ссылками

Поле или переменная типа Ссылка представляет собой класс LinkType, внутри которого присутствуют 2 поля:

public class LinkType
: BaseClass
{
public Guid? EntityId { get; set; } // идентификатор объекта, на который мы ссылаемся
public Guid? DataTypeId { get; set; } // идентификатор типа данных объекта, на который мы ссылаемся
}

Для работы со ссылками доступны следующие методы:

//ПолеСсылки - переменная типа Ссылка

ПолеСсылки.IsEmpty(); // вернет true, если EntityId == null && DataTypeId == null

ПолеСсылки.IsNullEntityId(); // вернет true, если EntityId == null
ПолеСсылки.IsNullDataTypeId(); // вернет true, если DataTypeId == null

ПолеСсылки.GetEntityId(); // вернет EntityId если он заполнен, иначе выкинет исключение
ПолеСсылки.GetDataTypeId()); // вернет DataTypeId он заполнен, иначе выкинет исключение8

ПолеСсылки.TryGetEntityId(out var entityId); // вернет true и заполнит entityId из EntityId, если он заполнен, иначе вернет false и в entityId будет пустой гуид

ПолеСсылки.TryGetDataTypeId(out var dataTypeId); // вернет true и заполнит dataTypeId из DataTypeId, если он заполнен, иначе вернет false и в dataTypeId будет пустой гуид

Metadata.DataTypes GetDataType(); //возвращает тип данных ссылки. Если тип не пределено, то вернет Empty

Также можно обращаться к полям напрямую:

bool hasEntityId = ПолеСсылки.EntityId.HasValue; // вернет true если заполнено
Guid entityId = ПолеСсылки.EntityId.Value // вернет значение или исключение, если значение не заполнено

Еще про работу с Nullable: https://docs.microsoft.com/ru-ru/dotnet/csharp/language-reference/builtin-types/nullable-value-types.

Другие функции

Свойства

  • CurrentProcessId.

  • LastException.

Проверки:

bool ok = IsNullOrDefault(object value)

Метаданные

Для работы с метаданными доступны следующие перечисления:

Тип метаданных

namespace

enum name

Методы поиска

Дополнительные методы

Тип данных

Metadata

DataTypes

MetadataInfo.SearchDataType

LinkType CreateLink(Guid entityId)

Динамический тип данных

Metadata

Dynamics

MetadataInfo.SearchDynamic

_

Перечисление

Metadata

Enums

MetadataInfo.SearchEnum

_

Метаданные систем

Metadata

SM

MetadataInfo.SearchSM

_

Алгоритм/Бизнес процесс

Metadata

Functions

MetadataInfo.SearchFunction

_

Система

Metadata

Systems

MetadataInfo.SearchSystem

SystemInfo GetSystemInfo()

Роли

Metadata

Roles

MetadataInfo.SearchRole

CredentialRole GetRoleInfo()

Обработчики

Metadata

Handlers

_

HandlerInfo GetHandlerInfo()

Методы поиска возвращают соответствующее значение перечисления. Если не найдено, то возвращается значение Empty. Поиск возможен по имени или Id объекта:

Metadata.* MetadataInfo.Search*(string name, bool caseInsensitive = false)
Metadata.* MetadataInfo.Search*(Guid id)

Для всех значений перечислений доступны методы:

Guid GetId(); //Внутренний идентификатор объекта*
string GetName(); //Имя объекта*

Генерируемые перечисления

Тип метаданных: Тип данных Перечисление: Metadata.DataTypes Методы расширения для перечисления:

Guid GetId()  возвращает идентификатор типа
string GetName()  возвращает название перечисления в виде строки
LinkType CreateLink(); - создает ссылку этого типа данных
LinkType CreateLink(Guid entityId);- создает ссылку этого типа данных с идентификатором entityId

Тип метаданных: Классификаторы Перечисление: Metadata.Classifiers Методы расширения для перечисления:

Guid GetId()  возвращает идентификатор классификатора
string GetName()  возвращает название перечисления в виде строки

Тип метаданных: Перечисления Перечисление: Metadata.Enums Методы расширения для перечисления:

Guid GetId()  возвращает идентификатор перечисления
string GetName()  возвращает название перечисления в виде строки

Тип метаданных: Функции Перечисление: Metadata.Functions Методы расширения для перечисления:

Guid GetId()  возвращает идентификатор функции
string GetName()  возвращает название перечисления в виде строки

Тип метаданных: Обработчики Перечисление: Metadata.Handlers Методы расширения для перечисления:

Guid GetId()  возвращает идентификатор обработчика
string GetName()  возвращает название перечисления в виде строки
HandlerInfo GetHandlerInfo()  возвращает класс с описанием обработчика
public class HandlerInfo
{
Guid Id //идентификатор обработчика
Name //имя
string Description //описание
ConnectorType ConnectorType //тип коннектора
PropertiesCollection Parameters // коллекция с параметрами обработчика
bool WaitResponse //ожидает ли ответа*
bool WaitArray //принимает массив или один элемент*
Metadata.DataTypes WaitDataType //какой тип данных принимает (опционально)
Metadata.SM WaitSystemDataType //какой тип метаданных принимает (опционально)
}
public enum ConnectorType
{
        None, _1C, File, Database, Custom, Web, WebSimple
}

Тип метаданных: Роли Перечисление: Metadata.Roles Методы расширения для перечисления:

Guid GetId()  возвращает идентификатор роли
string GetName()  возвращает название перечисления в виде строки
CredentialRole GetRoleInfo()  возвращает объект роли.

Тип метаданных: Системные типы (метаданные) Перечисление: Metadata.SM Методы расширения для перечисления:

Guid GetId()  возвращает идентификатор системного типа
string GetName()  возвращает название перечисления в виде строки

Тип метаданных: Системы Перечисление: Metadata.Systems Методы расширения для перечисления:

Guid GetId()  возвращает идентификатор системного типа
string GetName()  возвращает название перечисления в виде строки
SystemInfo GetSystemInfo()  возвращает объект с информацией о системе
Metadata.Systems GetSystemByGuid()  возвращает систему по идентификатору
class SystemInfo
{
bool IsActive; //включена
string[] Servers; //список серверов системы
ConnectorType ConnectorType; //тип коннектора
}

Прочие методы

DataTypesExtensions.DataTypes ById(Guid id)  возвращает значение перечисления типов данных по идентификатору
DataTypesExtensions.Classifiers ById(Guid id)  возвращает значение перечисления классификаторов по идентификатору
EnumsExtensions.Enums ById(Guid id)  возвращает значение перечисления по идентификатору
FunctionsExtensions.Functions ById(Guid id)  возвращает значение перечисления функций по идентификатору
HandlersExtensions.Handlers ById(Guid id)  возвращает значение перечисления обработчиков по идентификатору
RolesExtensions.Roles ById(Guid id)  возвращает значение перечисления ролей по идентификатору
SMExtensions.SM ById(Guid id)  возвращает значение перечисления системных типов по идентификатору
SystemsExtensions.Systems ById(Guid id)  возвращает значение перечисления систем по идентификатору

Программный модуль

Программные модули используются для написания простых общеиспользуемых функций.

Программный модуль можно создать в разделе Схемы обработки:

../_images/image161.png

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

../_images/outer_lib.png

В коде программного модуля пишется код функций, например:

public static int GetIntValue(int a)
{
return a+10;
}

Для вызова функции программного модуля в коде алгоритма или в шаге бизнес-процесса Пользовательский алгоритм используется синтаксис:

{userModules.Name}.{Имя функции в коде программного модуля}

Пример:

int i = ПрограммныйМодуль1.GetIntValue(5);

В программном модуле возможно использование логгера Logger. Для работы с функциями других серверов необходимо передавать фасады в качестве параметров явно.

Пример кода программного модуля:

public static void ПолучитьЗапись(Guid gu, IDataBankQuery DataBankQuery)
{
Гора Гора1 = new Гора();
Гора1 = DataBankQuery.Get<Гора>(gu);
Logger.Info($"Получена запись в программном модуле {Гора1}");
}

Пример кода алгоритма:

ПрограммныйМодуль1.ПолучитьЗапись(Guid.Parse("10000000-0000-0000-0000-000000000000"), DataBank);

Доступные фасады:

  • IDataBankQuery;

  • ICredentialQuery;

  • IOntologyManager.

Запуск вложенных БП/Алгоритмов из кода

Запуск вложенных Бизнес процессов и Алгоритмов:

Executor.Start(BP1); //запуск бизнес-процесса BP1 без ожидания
Executor.Execute(BP1); //запуск бизнес-процесса BP1 с ожиданием
var BP1 = new Вызываемый(); //Вызываемый - название БП
BP1.строка = "Привет"; //установка параметров
BP1.Сложное.число = 1; //установка параметров
Executor.Start(BP1); //запуск бизнес-процесса BP1 без ожидания
Executor.Execute(BP1); //запуск бизнес-процесса BP2 с ожиданием

Массивы

Функции доступные для массивов:

  • AddElement(): добавление значения по умолчанию в массив.

    Пример использования: mas.AddElement()

  • CreateElement(): создает, но не добавляет значение по умолчанию для массива.

    Пример использования: mas.CreateElement()

Работа с банком

  • Методы получения данных (Get/Exists/Query) доступны из трансформаторов, определения функций, алгоритмов и шагов Алгоритм.

  • Методы изменения данных (Write/Delete) доступны только из алгоритмов и шагов Алгоритм.

Методы, принимающие Message, ожидают в теле сообщения json с нужными объектами, а в DataType - идентификатор целевого типа.

Запись в банк

bool Write<T>(T entity, bool waitResponse = true) where T : IDataType;
bool Write<T>(T entity, out Guid entityId, bool waitResponse = true) where T : IDataType;

bool Write<T>(OwnList<T> entities, bool waitResponse = true) where T : IDataType;
bool Write<T>(OwnList<T> entities, out OwnList<Guid> entitiesIds, bool waitResponse = true) where T : IDataType;

bool Write(Message msg, bool waitResponse = false);
bool Write(Message msg, out Guid id, bool waitResponse = false);
bool Write(Message msg, out List<Guid> ids, bool waitResponse = false);

bool Write(OwnList<BaseClass> entitiesBase, bool waitResponse = true);
bool Write(OwnList<BaseClass> entitiesBase, out OwnList<Guid> entitiesIds, bool waitResponse = true);

bool Write(BaseClass entity, bool waitResponse = true);
bool Write(BaseClass entity, out Guid entityId, bool waitResponse = true);

Методы удаления

bool Delete(IDataType entity, bool waitResponse = true);

bool Delete<T>(Guid EntityId, bool waitResponse = true) where T : IDataType;

bool Delete(Guid EntityId, Guid typeId, bool waitResponse = true);
bool Delete(Guid EntityId, Metadata.DataTypes dataType, bool waitResponse = true);

bool Delete<T>(OwnList<T> entities, bool waitResponse = true) where T : IDataType;

bool Delete(LinkType link, bool waitResponse = true);
bool Delete(OwnList<LinkType> entities, bool waitResponse = true);

bool Delete(Message msg, bool waitResponse = true);

bool Delete<T>(T entity, bool waitResponse = true) where T : IDataType;
bool Delete<T>(OwnList<Guid> entitiesIds, bool waitResponse = true) where T : IDataType;

bool Delete(OwnList<Guid> entitiesIds, Guid typeId, bool waitResponse = true);
bool Delete(OwnList<Guid> entitiesIds, Metadata.DataTypes dataType, bool waitResponse =true);

bool Delete(BaseClass entity, bool waitResponse = true);
bool Delete(OwnList<BaseClass> entities, bool waitResponse = true);

Поиск данных

void Query(string query, Message message);
void QuerySimple(string query, Message message);
void QueryObject(string query, Message message);

void Query(string query, PropertiesCollection parameters, Message message);
void QuerySimple(string query, PropertiesCollection parameters, Message message);
void QueryObject(string query, PropertiesCollection parameters, Message message);

void Query<T>(string query, IList<T> resultList);
void QuerySimple<T>(string query, IList<T> resultList); OwnList<T> QuerySimple<T>(string query);
void QueryObject<T>(string query, IList<T> resultList); OwnList<T> QueryObject<T>(string query);

void Query<T>(string query, PropertiesCollection parameters, IList<T> resultList);
void QuerySimple<T>(string query, PropertiesCollection parameters, IList<T> resultList);
void QueryObject<T>(string query, PropertiesCollection parameters, IList<T> resultList);

Получение данных

T Get<T>(Guid entityId, Guid type = default) where T : new();
T Get<T>(LinkType type) where T : new();
OwnList<T> Get<T>(OwnList<Guid> entityIds);
OwnList<T> Get<T>(OwnList<LinkType> entityIds);

bool TryGet<T>(Guid entityId, out T val);
bool TryGet<T>(LinkType link, out T val);
bool TryGet<T>(OwnList<Guid> entityIds, out OwnList<T> val);

//В NotExists возвращается список неудач, возвращает true, если получен хотя бы один объект

bool TryGet<T>(OwnList<Guid> entityIds, out OwnList<T> val, out OwnList<Guid> notExists);
bool TryGet<T>(OwnList<LinkType> links, out OwnList<T> val);
bool TryGet<T>(OwnList<LinkType> links, out OwnList<T> val, out OwnList<LinkType> notExists);
bool TryGet<T>(OwnList<LinkType> links, out OwnList<T> val, out OwnList<Guid> notExists);

Проверка существования записей

//Методы для проверки на существование объектов, не существующие возвращаются в NotExists
//Для OwnList возвращает true, если найден хотя бы один объект и all==false. Возвращает true, если найдены все объекты и all==true.
bool Exists<T>(Guid entityId);
bool Exists(Guid entityId, Guid dataTypeId);
bool Exists(Guid entityId, Metadata.DataTypes dataType);
bool Exists(LinkType link);
bool Exists(OwnList<Guid> entityIds, out OwnList<Guid> notExists, Guid dataTypeId, bool all =
false);
bool Exists(OwnList<Guid> entityIds, out OwnList<Guid> notExists, Metadata.DataTypes
dataType, bool all = false);
bool Exists<T>(OwnList<Guid> entityIds, out OwnList<Guid> notExists, bool all = false);
bool Exists(OwnList<BaseClass> entities, out OwnList<LinkType> notExists, bool all = false);
bool Exists(OwnList<BaseClass> entities, out OwnList<BaseClass> notExists, bool all = false);
bool Exists(OwnList<IDataType> entities, out OwnList<LinkType> notExists, bool all = false);
bool Exists(IDataType entity);
bool Exists(Message entity);
bool Exists(BaseClass entity);
bool Exists(OwnList<IDataType> entities, out OwnList<IDataType> notExists, bool all = false);
bool Exists(OwnList<LinkType> links, out OwnList<LinkType> notExists, bool all = false);
bool Exists<T>(OwnList<LinkType> links, out OwnList<LinkType> notExists, bool all = false);

Credential (управление пользователями)

Подробное описание модуля управления пользователями находится в разделе Администратору

Для работы с метаданными Роли используется перечисление Metadata.Roles. Рекомендуется для работы с ролями использовать именно перечисление.

Структура типа CredentialUser

public Guid EntityId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Comment { get; set; }
public string Email { get; set; }
public bool IsEnabled { get; set; } = true;
public Guid FolderId { get; set; }

Структура типа CredentialFolder

public Guid EntityId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Comment { get; set; }
public Guid ParentId { get; set; }

Структура типа CredentialRole

public Guid EntityId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Comment { get; set; }
bool IsBusinessRole { get; set; }
OwnList<CredentialRole> Roles { get; set; } = new OwnList<CredentialRole>();

Методы для работы с пользователями/ролями/папками. Вызываются через объект Credential.

Пользователи

//Методы для работы с текущим пользователем
        bool IsAuthorized() //возвращает true, если в сообщении процесса был заполнен UserId
        CredentialUser GetCurrentUser() //возвращает текущего пользователя
        OwnList<Metadata.Roles> GetCurrentRoles(bool hierarchy = true) //возвращает роли текущего пользователя
        OwnList<Metadata.Roles> GetCurrentUserContainsRoles(bool hierarchy = true) //возвращает роли текущего пользователя, включая вложенные роли в бизнес-роли
        bool CurrentUserHasRole(Metadata.Roles role, bool hierarchy= true) //проверяет, установлена ли роль текущему пользователю
        bool CurrentUserHasContainsRole(Metadata.Roles role, bool hierarchy= true) //проверяет, установлена ли роль текущему пользователю, включая вложенные роли в бизнес-роли

//Чтение пользователей
        OwnList<CredentialUser> GetUsers(bool enabledOnly = true);

        CredentialUser GetUserById(Guid userId);
        CredentialUser TryGetUserById(Guid userId);

        CredentialUser GetUserByName(string name);
        CredentialUser TryGetUserByName(string name);

        CredentialUser GetUserByEmail(string email);
        CredentialUser TryGetUserByEmail(string email);

        bool UserExists(Guid userId);
        bool UserExists(string userName);
//Изменение пользователей
void AddUser(CredentialUser user);

void UpdateUser(CredentialUser user);

void DeleteUser(Guid userId);
void DeleteUser(string name);
void DeleteUser(CredentialUser user);

void DisableUser(Guid userId);
void DisableUser(CredentialUser user);
void DisableUser(string name);

void EnableUser(Guid userId);
void EnableUser(CredentialUser user);
void EnableUser(string name);

void SetPassword(Guid userId, string password);
void SetPassword(CredentialUser user, string password);
void SetPassword(string name, string password);

Группы пользователей

//Чтение групп
        OwnList<CredentialFolder> GetFolders();

        CredentialFolder GetFolderById(Guid folderId);
        CredentialFolder TryGetFolderById(Guid folderId);

        CredentialFolder GetFolderByName(string folderName, Guid? parentId = null, Guid? folderId= null);
        CredentialFolder TryGetFolderByName(string folderName, Guid? parentId = null, Guid?folderId = null);

        bool FolderExists(Guid folderId);
        bool FolderExists(string folderName);

//Изменение групп
        void AddFolder(CredentialFolder folder);

        void UpdateFolder(CredentialFolder folder);

        void DeleteFolder(Guid folderId);

        void DeleteFolder(CredentialFolder folder);

Иерархия пользователей и групп

//Получить группу
        CredentialFolder GetFolder(CredentialUser user);
        CredentialFolder GetFolder(CredentialFolder user);
        CredentialFolder GetFolderByUserId(Guid userId);

//Изменить группу
        void ChangeFolder(CredentialFolder folder, CredentialFolder parent);
        void ChangeFolder(CredentialUser user, CredentialFolder folder);

Роли

//Чтение ролей

        OwnList<CredentialRole> GetRoles();

        CredentialRole GetRoleById(Guid roleId);
        CredentialRole GetRoleByName(string roleName);

        bool RoleExists(Guid roleId);
        bool RoleExists(string roleName);

Роли пользователей и групп

//Чтение
        OwnList<Metadata.Roles> GetUserRoles(CredentialUser user, bool hierarchy = true);
        OwnList<Metadata.Roles> GetUserContainsRoles(CredentialUser user, bool hierarchy = true);

        bool UserHasRole(CredentialUser user, Metadata.Roles role, bool hierarchy= true);
        bool UserHasRole(CredentialUser user, Guid roleId, bool hierarchy= true);
        bool UserHasContainsRole(CredentialUser user, Metadata.Roles role, bool hierarchy = true);
        bool UserHasContainsRole(CredentialUser user, Guid roleId, bool hierarchy = true);

        OwnList<Metadata.Roles> GetFolderRoles(CredentialFolder folder, bool hierarchy = true);
        OwnList<Metadata.Roles> GetFolderContainsRoles(CredentialFolder folder, bool hierarchy =true);

        bool FolderHasRole(CredentialFolder folder, Metadata.Roles role, bool hierarchy= true);
        bool FolderHasRole(CredentialFolder folder, Metadata.Roles role, bool hierarchy= true);
        bool FolderHasRole(CredentialFolder folder, Guid roleId, bool hierarchy = true);
        bool FolderHasContainsRole(CredentialFolder folder, Metadata.Roles role, bool hierarchy=true);
        bool FolderHasContainsRole(CredentialFolder folder, Metadata.Roles role, bool hierarchy=true);
        bool FolderHasContainsRole(CredentialFolder folder, Guid roleId, bool hierarchy = true);

//Изменение
        void AddUserRole(CredentialUser user, Metadata.Roles role);
        void AddUserRole(Guid userId, Guid roleId);
        void AddUserRole(CredentialUser user, CredentialRole role);
        void AddUserRole(CredentialUser user, Guid roleId);

        void DeleteUserRole(CredentialUser user, Metadata.Roles role);
        void DeleteUserRole(Guid userId, Guid roleId);
        void DeleteUserRole(CredentialUser user, CredentialRole role);
        void DeleteUserRole(CredentialUser user, Guid roleId);

        void AddFolderRole(CredentialFolder folder, Metadata.Roles role);
        void AddFolderRole(CredentialFolder folder, Guid role);

        void DeleteFolderRole(CredentialFolder folder, Metadata.Roles role);
        void DeleteFolderRole(CredentialFolder folder, Guid role);

Дополнительные открытые и секретные свойства пользователей

//Чтение
PropertiesCollection GetAdditionalProperties(CredentialUser user);
T GetAdditionalProperty<T>(CredentialUser user, string propertyName);
PropertiesCollection GetSecretProperties(CredentialUser user);
T GetSecretProperty<T>(CredentialUser user, string propertyName);

bool AdditionalPropertyExists(string propertyName);
bool SecretPropertyExists(string propertyName);

//Изменени
void SetAdditionalProperties(CredentialUser user, PropertiesCollection collection);
void SetAdditionalProperty<T>(CredentialUser user, string propertyName, T value);

void SetSecretProperties(CredentialUser user, PropertiesCollection collection);
void SetSecretProperty<T>(CredentialUser user, string propertyName, T value);

Значения параметров

Параметр hierarchy - учитывать роли, установленные для родительских элементов.

Примеры использования методов Credential в шаге Алгоритм бизнес процесса.

Для использования примеров создать Бизнес-процесс с шагом Алгоритм, и выполнять его, например, через триггер.

Добавление пользователя

Код в алгоритме:

CredentialUser User1 = new CredentialUser();
User1.EntityId = Guid.NewGuid();
User1.Name = "Vasya3";
User1.Description = "Vasya Pupkin";
User1.Comment = "123";
User1.Email = "name1@gmail.com";
User1.IsEnabled = true;
Credential.AddUser(User1);

Обновление пользователя

Код в алгоритме:

CredentialUser User1 = Credential.GetUserByName("Vasya3");
User1.Name = "Vova";
User1.Description = "Vova Ivanov";
User1.Comment = "321";
User1.Email = "name1@gmail.com";
User1.IsEnabled = true;
Credential.UpdateUser(User1);

Установление пароля

Код в алгоритме:

Credential.SetPassword(Guid.Parse("9739520D-D795-4893-BA5E-EE937BD83611"), "Pwd");

Отключение / Включение пользователя

Код в алгоритме:

Credential.DisableUser(Guid.Parse("9739520D-D795-4893-BA5E-EE937BD83611"));

Или

Credential.EnableUser(Guid.Parse("9739520D-D795-4893-BA5E-EE937BD83611"));

Добавление дополнительных свойств

В конфигурации Credential добавить

"additionalFields": [
                {
                        "$type": "DT.MdmMetadata.BusinessProcesses.Fields.SimpleField, DT_Core",
                        "type": "String",
                        "name": "Религия",
                        "id": "c41bed87-8a55-4c6e-8874-0b6b0f3e389e",
                        "isArray": false,
                        "isRequired": false,
                        "isNullable": false,
                        "properties": {
                        "$type": "System.Collections.Generic.Dictionary`2[[System.String,
                        System.Private.CoreLib],[System.String, System.Private.CoreLib]], System.Private.CoreLib"
                }
        }
]

Код в алгоритме:

CredentialUser user1 = Credential.GetUserByName("Vasya3");
Credential.SetAdditionalProperty(user1, "Религия", "джедай");

Или использовать

CredentialUser user1 = Credential.GetUserByName("Vasya3");
PropertiesCollection addcollection = Credential.GetAdditionalProperties(user1);
addcollection.AddValue( "Религия", "джедай");
Credential.SetAdditionalProperties(user1, addcollection);

Добавление секретного свойства

В конфигурации Credential добавить

"secretFields": [
                {
                "$type": "DT.MdmMetadata.BusinessProcesses.Fields.SimpleField, DT_Core",
                "type": "Decimal",
                "decimalOptions": {
                "$type": "DT.MdmMetadata.Types.DecimalOptions, DT_TypeBuilder.Entities",
                "precision": 10,
                "scale": 0,
                "autoRound": false
                },
                "name": "Зарплата",
                "id": "c41bed87-8a55-4c6e-8874-0b6b0f3e389e",
                "isArray": false,
                "isRequired": false,
                "isNullable": false,
                "properties": {
                "$type": "System.Collections.Generic.Dictionary`2[[System.String, System.Private.CoreLib],[System.String, System.Private.CoreLib]], System.Private.CoreLib"
                }
        }
],

Код в алгоритме:

CredentialUser user1 = Credential.GetUserByName("Vasya3");
Credential.SetSecretProperty(user1, "Зарплата", "123123");

Или используйте следующий код:

CredentialUser user1 = Credential.GetUserByName("Vasya3");
PropertiesCollection secretcollection = Credential.GetSecretProperties(user1);
secretcollection.AddValue("Зарплата", "123123");
Credential.SetSecretProperties(user1, secretcollection);

Удаление пользователя

Код в алгоритме:

Credential.DeleteUser(Guid.Parse("577297B5-C5E5-439A-B966-251F9D4811FC"));

Добавление папки в таблицу dbo.folders

Код в алгоритме:

CredentialFolder fold1 = new CredentialFolder();
fold1.EntityId = Guid.NewGuid();
fold1.Name = "FolderVasya6";
fold1.Description = "Folder6";
fold1.Comment = "1236";
Credential.AddFolder(fold1);

Добавление пользователя в таблицу dbo.folders

Код в алгоритме:

CredentialUser User1 = new CredentialUser();
User1.EntityId = Guid.NewGuid();
User1.Name = "Vasya3";
User1.Description = "Vasya Pupkin";
User1.Comment = "123";
User1.Email = "name1@gmail.com";
User1.IsEnabled = true;
Credential.AddUser(User1);

Обновление папки

Код в алгоритме:

var propId1 = Guid.Parse("CB7EB008-8DC3-4C5A-8A11-6163D72D2EE0");
CredentialFolder fold1 = Credential.GetFolderById(propId1);
fold1.Name = "FolderVasya_up";
fold1.Description = "Folder_update";
fold1.Comment = "123_update";
Credential.UpdateFolder(fold1);

Изменение папки у пользователя

Код в алгоритме:

CredentialUser user1 = Credential.GetUserByName("Vasya3");
Logger.Info($"begin TEST777_DT251_aaa");
CredentialFolder fold1 = Credential.GetFolderById(Guid.Parse("E55F1242-B391-4A80-BC72-
93BC107342B2"));
Logger.Info($"begin TEST777_DT251_bbb");
Credential.ChangeFolder(user1, fold1);

Удаление папки

Код в алгоритме:

CredentialFolder fold1 = Credential.GetFolderById(Guid.Parse("E4D9CB4C-3F26-4FF4-B7A9-
F6A7EF3AAD4D"));
Credential.DeleteFolder(fold1);

Получение ролей пользователя

Код в алгоритме:

CredentialUser user1 = Credential.GetUserByName("ИмяПользователя");
OwnList<Metadata.Roles> roles = Credential.GetUserRoles(user1, true);
Logger.Info($"Пользователь: {user1}");
foreach(Metadata.Roles role in roles)
{
Logger.Info($"Роли GetUserRoles true: {role}");
}
OwnList<Metadata.Roles> roles1 = Credential.GetUserRoles(user1, false);
Logger.Info($"Пользователь: {user1}");
foreach(Metadata.Roles role in roles1)
{
Logger.Info($"Роли GetUserRoles false: {role}");
}
OwnList<Metadata.Roles> roles2 = Credential.GetUserContainsRoles(user1, true);
Logger.Info($"Пользователь: {user1}");
foreach(Metadata.Roles role in roles2)
{
Logger.Info($"Роли GetUserContainsRoles true: {role}");
}
OwnList<Metadata.Roles> roles3 = Credential.GetUserContainsRoles(user1, false);
Logger.Info($"Пользователь: {user1}");
foreach(Metadata.Roles role in roles3)
{
Logger.Info($"Роли GetUserContainsRoles false: {role}");
}

Роли Credential в управлении пользователями

Добавление роли в ЦУ и в Credential

Создайте роль в ЦН. Для этого перейдите в раздел Публикация данныхРоли и нажмите на кнопку + в рабочей области.

Получить роли можно в Swagger по запросу:

GET /api/metadata/roles - Получить роли

Код в алгоритме:

Credential.AddUserRole(Guid.Parse("85FC1A65-B0D8-4F5E-994E-8C5BEA6C6A61"),
Guid.Parse("385ff9bd-6006-45be-913b-c97fdba002e9"));

Где, первый Guid - пользователя, второй Guid - роли.

Добавление роли в папку Credential

Код в алгоритме:

CredentialFolder fold = Credential.TryGetFolderByName("FolderVasya");
Credential.AddFolderRole(fold, Guid.Parse("88d1af76-e997-4ef2-9ade-dd4efe20af07"));

Где, FolderVasya имя созданной ранее папки, Guid - роли.

Удаление роли Credential

Код в алгоритме:

Credential.DeleteUserRole(Guid.Parse("85FC1A65-B0D8-4F5E-994E-8C5BEA6C6A61"),
Guid.Parse("385ff9bd-6006-45be-913b-c97fdba002e9"));

Где, первый Guid - пользователя, второй Guid - роли.

Удаление роли из ЦУ

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

При удалении роли из ЦУ удалятся записи в таблице role_users и role_folders.

Внешние пользователи Credential

Добавление внешнего пользователя Credential

  1. Откройте Swagger узла и найдите следующий метод:

POST/api/credential/externalUsers/users - Добавить пользователя

  1. Заполните все необходимые данные, например:

    {
            "name": "user01",
            "login": "user01",
            "description": "user01test",
            "comment": "comment111",
            "systemId": "0abb2f56-30bf-4b4b-8049-2e8ae592892f",
            "internalUserId": "90AD1E95-BA6F-4AE0-8E1B-1CF2D74FAAA4"
    }
    

Где

  • entityId - Идентификатор внешнего пользователя (в примере пустой, чтобы сгенерировался автоматически)

  • name - Имя внешнего пользователя;

  • login - Логин, если для авторизации во внешней системе, нужно написать например домен перед именем, тогда в этом поле будет реальная строка для ввода логина юзера при авторизации;

  • description - Описание внешнего пользователя;

  • comment - Комментарий;

  • systemId - Идентификатор системы, модуля, который использует эту учетную запись;

  • internalUserId - Идентификатор пользователя Credential.

Установка пароля внешнему пользователю Credential

Открытый ключ действителен в течении 1 минуты. По истечении времени необходимо запросить снова открытый ключ.

  1. Выполнить метод, указав идентификатор внешнего пользователя:

Get/api/credential/externalUsers/publicKey - Получить ключ для шифрования пароля Скопировать полученный ключ.

  1. Выполнить метод, указав пароль и скопированный ключ:

Get/api/credential/externalUsers/users/test-encrypt - Тестовый метод шифрования данных

  1. Выполнить метод, указав идентификатор внешнего пользователя и зашифрованный пароль:

Get/api/credential/externalUsers/password - Установить пароль

Получить внешнего пользователя по имени

В Swagger узла найти следующий метод:

GET/api/credential/externalUsers/users - Получить внешних пользователей по имени.

Удалить внешнего пользователя Credential

В Swagger узла найти следующий метод:

DELETE api/credential/externalUsers/users/{id} - Удалить внешнего пользователя.

Транспортные функции

В алгоритмах и процессах для регистрации и отправки сообщений доступен фасад Transport.

Отправка сообщения получателям:

void SendMessage(Message message, OwnList<Guid> receivers, Guid? handlerId = null);
void SendMessage(string message, OwnList<Guid> receivers, Guid? handlerId = null);
void SendMessage(BaseClass message, OwnList<Guid> receivers, Guid? handlerId = null);
void SendMessage(byte[] message, OwnList<Guid> receivers, Guid? handlerId = null);

void SendMessage(Message message, Guid receiver, Guid? handlerId = null);
void SendMessage(string message, Guid receiver, Guid? handlerId = null);
void SendMessage(BaseClass message, Guid receiver, Guid? handlerId = null);
void SendMessage(byte[] message, Guid receiver, Guid? handlerId = null);

void SendMessage(Message message, string searchPattern, Guid? handlerId = null);
void SendMessage(BaseClass message, string searchPattern, Guid? handlerId = null);
void SendMessage(string message, string searchPattern, Guid? handlerId = null);
void SendMessage(byte[] message, string searchPattern, Guid? handlerId = null);

void SendMessage(Message message, Metadata.Systems system, Metadata.Handlers? handler = null);
void SendMessage(Message message, OwnList<Metadata.Systems> systems, Metadata.Handlers? handler = null);
void SendMessage(string message, Metadata.Systems system, Metadata.Handlers? handler = null);
void SendMessage(string message, OwnList<Metadata.Systems> systems, Metadata.Handlers? handler = null);
void SendMessage(byte[] message, Metadata.Systems system, Metadata.Handlers? handler = null);
void SendMessage(byte[] message, OwnList<Metadata.Systems> systems, Metadata.Handlers? handler = null);
void SendMessage(BaseClass message, Metadata.Systems system, Metadata.Handlers? handler = null);
void SendMessage(BaseClass message, OwnList<Metadata.Systems> systems, Metadata.Handlers? handler = null);

Отправка ответного сообщения источнику:

SendResponseMessage(Message message);
SendResponseMessage(string message);
SendResponseMessage(BaseClass message);
SendResponseMessage(byte[] message);
SendResponseMessage(Message message, Message request);
SendResponseMessage(string message, Message request);
SendResponseMessage(BaseClass message, Message request);
SendResponseMessage(byte[] message, Message request);

Регистрация нового сообщения для обработки - регистрирует сообщение для обработки на узле, сообщение попадает в определятор:

RegisterMessage(Message message);
RegisterMessage(BaseClass message);
RegisterMessage(string message);
RegisterMessage(byte[] message);

Типы данных

Тип DateTime

Работа с датами выполняется с учетом Kind. Для сравнения дат рекомендуется также учитывать Kind и использовать методы сравнения https://docs.microsoft.com/ru-ru/dotnet/api/system.datetime.compare?view=net-5.0.

Тип DataType

Все объекты DataType, а также сложные переменные унаследованы от класса BaseClass.

Контейнер BaseClass

Все объекты DataType, SystemDataType, а также сложные переменные унаследованы от класса BaseClass.

Доступные методы и свойства:

bool IsDefault() //Возвращает true, если все поля объекта заполнены значениями по умолчанию
Metadata.DataTypes GetDataType() //значение перечисления Types.DataTypes, соответствующее типу текущего объекта

Ссылка LinkType

Объект LinkType описывает ссылку на объект. Содержит 2 поля:

  • Guid EntityId

  • Guid DataTypeId

Создать ссылку можно с помощью метода CreateLink из Metadata.DataType:

LinkType Metadata.DataTypes.MyType.CreateLink();
LinkType Metadata.DataTypes.MyType.CreateLink(Guid entityId);

Поддерживает неявное преобразование в тип Guid, т.е. можно написать так:

LinkType lt = new LinkType();
Guid dd = lt; // будет установлено значение поля EntityId

Интерфейсы

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

Доступны встроенные механизмы для работы с интерфейсами:

тип1.CopyTo((IМойИнтерфейс)тип2); //в тип2 копируются поля интерфейса IМойИнтерфейс из тип1

Системные поля

Если у типа данных проставлен признак Объект банка данных, то при сохранении такого типа система создает таблицу указанной пользователем структуры и класс DataInfo c сервисными полями:

  • DateTime created NOT NULL;

  • DateTime updated NOT NULL;

  • guid version NOT NULL.

Данные поля не отображаются в центре настройки.

../_images/image197.png

Заполнение сервисных полей:

1. DateTime created Заполняется текущей датой сервера на момент записи для запроса insert Пример, при выполнении шага Запись. Формат даты в UTC.

2. DateTime updated Заполняется тек датой сервера на момент записи для запроса insert или update.

При обновлении данных у типа, система заменила дату обновления:

../_images/image21.png
  1. guid version - заполняется из принятого сообщения в банк.

Получить значения системные полей можно при использовании шагов:

  • Получение Объекта;

  • Поиск;

  • Шаги запроса.

Пример получения значений системных полей:

синтаксис <ТипДанных>.<НазваниеСистемногоПоля>=“<дата>“

Шаг Поиск: в строке поиска написать Животные.Created :“2022-05-2406:22:23.1600000“. При выполнении шага Поиск система вернет ответ следующей структуры:

../_images/image22.png
../_images/image231.png

Утилиты

Утилиты по трансформации тела сообщения UserModuleUtils

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

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

Функции копирования

/// <summary>
/// Копирование параметров тела сообщения
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="copyProps">Параметры для копирования</param>
/// <param name="appendIfNotExists">Признак - добавлять параметр если не существует</param>
/// <returns><c>true</c> операция завершена успешно, <c>false</c> иначе</returns>
bool CopyTo(Message message, OwnDictionary<string, string> copyProps, bool appendIfNotExists = true)
/// <summary>
/// Копирование параметров тела сообщения
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="copyProps">Параметры для копирования</param>
/// <param name="appendIfNotExists">Признак - добавлять параметр если не существует</param>
/// <returns><c>true</c> операция завершена успешно, <c>false</c> иначе</returns>
bool CopyTo(Message message, OwnDictionary<string, OwnList<string>> copyProps, bool appendIfNotExists = true)
/// <summary>
/// Копирование параметров тела сообщения
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="xpathFrom">Путь к свойству источнику</param>
/// <param name="xpathTo">Путь к свойству назначения</param>
/// <param name="appendIfNotExists">Признак - добавлять параметр если не существует</param>
/// <returns><c>true</c> операция завершена успешно, <c>false</c> иначе</returns>
bool CopyTo(Message message, string xpathFrom, string xpathTo, bool appendIfNotExists = true)
/// <summary>
/// Копирование параметров тела для строки
/// </summary>
/// <param name="data">Строка содержащая JSON или XML</param>
/// <param name="dataType">Тип данных в строке</param>
/// <param name="copyProps">Параметры для копирования</param>
/// <param name="dataResult">Переменная для результата копирования</param>
/// <param name="appendIfNotExists">Признак - добавлять параметр если не существует</param>
/// <returns><c>true</c> операция завершена успешно, <c>false</c> иначе</returns>
bool CopyTo(string data, MessageBodyType dataType, OwnDictionary<string, OwnList<string>> copyProps, out string dataResult, bool appendIfNotExists = true)
/// <summary>
/// Копирование параметров тела для массива байт
/// </summary>
/// <param name="data">Строка содержащая JSON или XML в виде массива байт</param>
/// <param name="dataType">Тип данных в строке</param>
/// <param name="copyProps">Параметры для копирования</param>
/// <param name="dataResult">Переменная для результата копирования</param>
/// <param name="appendIfNotExists">Признак - добавлять параметр если не существует</param>
/// <returns>Результат копирования в строке</returns>
bool CopyTo(byte[] data, MessageBodyType dataType, OwnDictionary<string, OwnList<string>> copyProps, out byte[] dataResult, bool appendIfNotExists = true)

Функции установки значения

<code csharp>
/// <summary>
/// Установка параметров по указанному xpath
/// </summary>
/// <param name="message">сообщение</param>
/// <param name="copyProps">Параметры для копирования</param>
/// <param name="appendIfNotExists">Признак - добавлять параметр если не существует</param>
/// <returns><c>true</c> операция завершена успешно, <c>false</c> иначе</returns>
bool SetValue(Message message, OwnDictionary<string, object> copyProps, bool appendIfNotExists = true)
/// <summary>
/// Установка параметра по указанному xpath
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="xpathTo">Путь к свойству</param>
/// <param name="value">Значение</param>
/// <param name="appendIfNotExists">Признак - добавлять параметр если не существует</param>
/// <returns></returns>
bool SetValue(Message message, string xpathTo, object value, bool appendIfNotExists = true)
/// <summary>
/// Установка параметров по списку свойств
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="copyProps">Параметры копирования</param>
/// <param name="appendIfNotExists">Признак - добавлять параметр если не существует</param>
/// <returns><c>true</c> операция завершена успешно, <c>false</c> иначе</returns>
bool SetValue(Message message, OwnDictionary<string, OwnList<string>> copyProps, bool appendIfNotExists = true)
/// <summary>
/// Установка параметра по списку свойств
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="xpathTo">Параметры копирования</param>
/// <param name="xpathExpressionFrom">Набор параметров содержащих значения</param>
/// <param name="appendIfNotExists">Признак - добавлять параметр если не существует</param>
/// <returns><c>true</c> операция завершена успешно, <c>false</c> иначе</returns>
bool SetValue(Message message, string xpathTo, OwnList<string> xpathExpressionFrom, bool appendIfNotExists = true)
/// <summary>
/// Установка свойств по пути
/// </summary>
/// <param name="data">Исходные данные в виде строки XML или JSON</param>
/// <param name="dataType">Тип данных в строке</param>
/// <param name="copyProps">XPath пути свойств для копирования</param>
/// <param name="appendIfNotExists">Признак - создавать свойство если его нет</param>
/// <returns>Полученная строка после установки значения</returns>
string SetValue(string data, MessageBodyType dataType, OwnDictionary<string, object> copyProps, bool appendIfNotExists = true)
/// <summary>
/// Установка свойств по пути
/// </summary>
/// <param name="data">Исходные данные в виде массива байт из строки XML или JSON</param>
/// <param name="dataType">Тип данных в строке</param>
/// <param name="copyProps">XPath пути свойств для копирования</param>
/// <param name="appendIfNotExists">Признак - создавать свойство если его нет</param>
/// <returns>Полученная строка после установки значения</returns>
byte[] SetValue(byte[] data, MessageBodyType dataType, OwnDictionary<string, object> copyProps, bool appendIfNotExists = true)
/// <summary>
/// Установка свойств по пути
/// </summary>
/// <param name="data">Исходные данные в виде строки XML или JSON</param>
/// <param name="dataType">Тип данных в строке</param>
/// <param name="copyProps">XPath пути свойств для копирования</param>
/// <param name="appendIfNotExists">Признак - создавать свойство если его нет</param>
/// <returns></returns>
string SetValue(string data, MessageBodyType dataType, OwnDictionary<string, OwnList<string>> copyProps, bool appendIfNotExists = true)
/// <summary>
/// Установка свойств по пути
/// </summary>
/// <param name="data">Исходные данные в виде массива байт из строки XML или JSON</param>
/// <param name="dataType">Тип данных в строке</param>
/// <param name="copyProps">XPath пути свойств для копирования</param>
/// <param name="appendIfNotExists">Признак - создавать свойство если его нет</param>
/// <returns></returns>
byte[] SetValue(byte[] data, MessageBodyType dataType, OwnDictionary<string, OwnList<string>> copyProps, bool appendIfNotExists = true)

Функции получения значения

/// <summary>
/// Получение значения свойства по xpath
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="xpath">Путь к параметру</param>
/// <param name="throwErrorIfNotFound">Формировать исключение если параметр не
найден</param>
/// <returns><c>true</c> операция завершена успешно, <c>false</c> иначе</returns>
string GetValue(Message message, string xpath, bool throwErrorIfNotFound = false)
/// <summary>
/// Получение значения свойства из XML или JSON
/// </summary>
/// <param name="data">Строка содержащая XML или JSON</param>
/// <param name="dataType">Тип данных в строке</param>
/// <param name="xpathTo">Путь к свойству</param>
/// <param name="throwErrorIfNotFound">Формировать исключение, если не найдено
свойство</param>
/// <returns></returns>
string GetValue(string data, MessageBodyType dataType, string xpathTo, bool
throwErrorIfNotFound = false)
/// <summary>
/// Получение значения свойства из XML или JSON
/// </summary>
/// <param name="data">Массив байт строки содержащей XML или JSON</param>
/// <param name="dataType">Тип данных в строке</param>
/// <param name="xpathTo">Путь к свойству</param>
/// <param name="throwErrorIfNotFound">Формировать исключение, если не найдено
свойство</param>
/// <returns></returns>
byte[] GetValue(byte[] data, MessageBodyType dataType, string xpathTo, bool
throwErrorIfNotFound = false)

Функции конвертации

/// <summary>
/// Преобразование тела сообщения из XML в JSON
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="ignoreRoot">Игнорировать корневой элемент</param>
/// <returns><c>true</c> преобразовано</returns>
bool BodyXmlToJson(Message message, bool ignoreRoot=false)
/// <summary>
/// Преобразование тела сообщения из JSON в XML
/// </summary>
/// <param name="message">Сообщение</param>
/// <param name="rootName">Название корневого элемента XML</param>
/// <returns><c>true</c> преобразовано</returns>
bool BodyJsonToXML(Message message, bool addRoot = false, string rootName = "root")
/// <summary>
/// Функция трансформации JSON в XML
/// </summary>
/// <param name="data">Строка содержащая JSON</param>
/// <returns></returns>
string TransformToXML(string data)
/// <summary>
/// Функция трансформации XML в JSON
/// </summary>
/// <param name="data">Строка содержащая XML</param>
/// <returns></returns>
string TransformToJSON(string data)
/// <summary>
/// Функция трансформации XML в JSON
/// </summary>
/// <param name="data">Массив байт строки содержащей XML</param>
/// <returns></returns>
byte[] TransformToJSON(byte[] data)
/// <summary>
/// Функция трансформации JSON в XML
/// </summary>
/// <param name="data">Массив байт строки содержащей JSON</param>
/// <returns></returns>
byte[] TransformToXML(byte[] data)

Пример использования в программном модуле UserModule

//Копирование свойств по пути с созданием свойства назначения если нет
public static void CopyNameProp(Message message){
//Ищем в свойстве name
var xpathFrom="name";
//Копируем в friends/name
var xpathTo="friends[0]/name";
//Скопирует значени свойства, если свойства
//источника xpathFrom нет, копирование не производится
//если нет назначения xpathTo то создается свойство и в него копируется значение
UserModuleUtils.CopyTo(message,xpathFrom,xpathTo);
}
//Копирование свойств по пути с созданием свойства назначения если нет
public static void CopyNameProps(Message message){
var propsList=new OwnDictionary<string, OwnList<string>> {
{"name",new OwnList<string> {"friends[0]/name"}},
{"name",new OwnList<string> {"second-name"}},
{"name",new OwnList<string> {"fill-name"}},
};
//Скопирует значени свойства, если свойства
//источника xpathFrom нет, копирование не производится
//если нет назначения xpathTo то создается свойство и в него копируется значение
UserModuleUtils.CopyTo(message,propsList);
}
//Установка свойства
public static void SetValuesProps(Message message){
var propsList=new OwnDictionary<string,object> {
{"name","Иванов"},
{"second-name","Иван"},
{"fill-name","Иванович"}
};
//Установит значения для свойств:
//"name":"Иванов"
//"second-name":"Иван"
//"fill-name":"Иванович"
UserModuleUtils.SetValue(message,propsList);
}
public static void SetValueProp(Message message){
//Установит значения для свойств:
//"name":"Иванов"
UserModuleUtils.SetValue(message,"name","Тест");
}
//Установка свойства по формуле
public static void SetValues(Message message){
var propsList=new OwnDictionary<string, OwnList<string>> {
{"name",new OwnList<string>{
"friends[0]/name",
"friends[1]/name",
"friends[2]/name"
}}
};
//Установит значения для свойств:
//"name":"friends[0]/name" + "friends[1]/name" + "friends[2]/name"
UserModuleUtils.SetValue(message,propsList);
}
//Получение значения
public static string GetValues(Message message){
var path="friends[0]/name";
//Вернет значение свойства friends[0]/name
return UserModuleUtils.GetValue(message,path);
}
//Трансформация XML в JSON
public static bool ToJson(Message message){
return UserModuleUtils.BodyXmlToJson(message);
}

Пример использования во входящем транформаторе функций модуля UserModule

var mess=InitMessage;
var obj=mess.GetBodyAsString();
Logger.Verbose(obj);
if(mess.GetBodyType()==MessageBodyType.JSON){
UserModule.CopyNameProp(mess);
obj=mess.GetBodyAsString();
Logger.Verbose($"После копирования friends[0]/name будет \"Dolly Walter\" {obj}");
UserModule.CopyNameProps(mess);
obj=mess.GetBodyAsString();
Logger.Verbose($"После копирования friends[0]/name будет \"Dolly Walter\", добавятся еще
свойства second-name и fill-name с значением \"Dolly Walter\" {obj}");
UserModule.SetValuesProps(mess);
obj=mess.GetBodyAsString();
Logger.Verbose($"После установки значений свойства name:\"Иванов\" second-
name:\"Иван\" fill-name:\"Иванович\" {obj}");
UserModule.SetValueProp(mess);
obj=mess.GetBodyAsString();
Logger.Verbose($"После установки значений name:\"Тест\" {obj}");
UserModule.SetValues(mess);
obj=mess.GetBodyAsString();
Logger.Verbose($"После установки значений name:\"Dolly WalterHarris KnightSalazar
Decker\" {obj}");
var value_=UserModule.GetValues(mess);
Logger.Verbose($"Получение значения friends[0]/name {value_}");
}
else if(mess.GetBodyType()==MessageBodyType.XML){
if(!UserModule.ToJson(mess)){
Logger.Info("Ошибка преобразования тела в JSON");
}
else{
Logger.Info($"Преобразование тела, было тело {obj} после трансформации
{mess.GetBodyAsString()}");
}
}

Коллекция свойств

Класс PropertiesCollection предназначен для работы со словарем свойств, где ключ - это строка (название свойства), а значение - это само свойство. Свойства могут быть простые и списковые. Простые свойства содержат одно значение указанного типа, списковые - соответственно список значений. Поддерживаются следующие типы свойств:

  • string;

  • int;

  • decimal;

  • bool;

  • DateTime;

  • Guid.

Также для типов int/decimal/bool/DateTime/Guid доступны из варианты с Nullable (int?/decimal?/bool?/DateTime?/Guid?). Чтобы создать переменную типа Коллекция свойств, нужно в ЦН выбрать тип переменной Прочие - Коллекция свойств, либо можно вручную в коде алгоритма:

var collection = new PropertiesCollection();

Методы класса PropertiesCollection

Внимание

Во все методы вместо string name можно передавать значение перечисления MessageProperties.

Добавление свойств

//Если такое свойство уже есть - то ничего не произойдет
void AddValue<T>(string name, T value)
AddValueList<T>(string name, OwnList<T> valueList) //Добавление спискового свойства
//если такое свойство уже есть - перезапишется новым значением
void Set<T>(string name, T value)
void SetValueList<T>(string name, OwnList<T> value)

Получение свойств

T GetValue<T>(string name) //если свойства нет или у него другой тип - будет исключение
bool TryGetValue<T>(string name, out T value) //если свойства нет или у него другой тип - то вернет false, а в value будет значение по умолчанию для этого типа
bool TryGetValueList<T>(string name, out OwnList<T> values)
OwnList<T> GetValueList<T>(string name)

Удаление свойств

void Remove(string name) //если свойство есть - оно будет удалено

Прочие методы

Type GetPropertyType(string name) // Получить тип для свойства сообщения
bool Has(string name) //есть ли такое свойство любого типа
bool Has<T>(string name) //есть ли такое свойство типа Т
bool HasList<T>(string name)//есть ли такое списковое свойство типа Т
bool IsNull(string name) //в значении свойства null?. Если свойства нет - исключение
void Clear() //очищает коллекцию
bool IsDefault // возвращает true, если коллекция пустая
bool IsEqual(PropertiesCollection input) // возвращает true, если коллекции содержат одинаковые свойства
void CopyFrom(PropertiesCollection collection) // копирует свойства из переданной коллекции в текущую. Существующие перезапишутся, те, которых нет в переданной коллекции остаются

Онтология

Первичная настройка

  1. Создать модуль онтологии, указать параметры подключения к СУБД.

  2. Создать классификатор, указать ИД модуля онтологии.

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

Функции онтологии

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

Ontology.UseClassifier (GUID classifierId)

Управление классификатором

Добавление классов в классификатор

Ontology.AddClass(GUID classId1)

Добавление свойств в классификатор v

Создание коллекции свойств

var properities = new List<Property>();
var propId1 = Guid.Parse("6284807c-6486-4228-b6de-b0c5ddf3fba1");
properities.Add(new Property(propId1, "String"));
где String - это тип свойств (варианты String, Number, Category).

Регистрация коллекции

Ontology.SetClassProperty(classId1, properties);

Удаление класса

Ontology.DeleteClass(Guid classId)

Получение массива зарегистрированных классов

Ontology.GetClasses()

Возвращает список идентификаторов классов(Guid).

Проверка существования класса и его свойств

Поиск классов по идентификатору

Ontology.FindClasses(List<Guid> classIds)

Возвращает словарь вида <Guid idClass, bool exist>, где idClass - идентификатор класса, exist - признак наличия.

Получение свойств классов

Ontology.GetProperties(List<Guid> classIds)

Возвращает список объектов Property.

Получение свойств класса

Ontology.GetProperties(Guid classId)

Возвращает список объектов Property.

Удаление всех классов, их свойств и примеров

Ontology.DeleteAll()

Управление примерами

Добавление примеров

var CurrentExamples = new List<Example>();
var classId3 = Guid.Parse("9C374457-F031-4777-8BC9-785FC85B29ED");
var input = "Шлифмашинка угловая 9069F MAKITA (ф230мм, 2000Вт, 6600об/м, 4.2кг, кор, суперфлянец)";
var example = new Example(input, classId1, new List<PropertyValue>()); //или new
Example(Guid.NewGuid(), input, classId1, new List<PropertyValue>())
example.Properties.Add(new PropertyValue(propId1, input, 33, 42));
example.Properties.Add(new PropertyValue(propId2, input, 19, 31));
CurrentExamples.Add(example);
Ontology.AddAndLearnExamples(CurrentExamples);

Переобучение по ранее добавленным примерам

Ontology.TrainClassifier();

Удаление примеров

Ontology.DeleteExamples();

Удаление примеров для класса

Ontology.DeleteExamplesByClass(Guid classId);

Удаление примера

Ontology.DeleteExample(Guid id);

где id - идентификатор удаляемого примера.

Обновление примера

Ontology.UpdateExample(Example example);

Получение примеров

Ontology.GetExamples();

Возвращает список объектов Example.

Получение примеров для класса

Ontology.GetExamplesByClass(Guid classId);

Возвращает список объектов Example.

Получение примера по идентификатору

Example Ontology.GetExample(Guid exampleId);

Возвращает объект Example, если пример существует. Если пример не существует, то срабатывает исключение NotExistsException.

bool Ontology.TryGetExample(Guid exampleId, out Example example)

Получение примера по содержимому:

Ontology.GetExampleByContent(string content);

Возвращает объект Example или null.

Классификация и извлечение характеристики

Классификация

var classes = Ontology.Classify("Шуруповерт аккум.BOSCH PSR", true);

Возвращает объект OwnList<KeyValuePair<Guid, UniqueTotalTuple>>.

Извлечение характеристик

var properties = Ontology.ExtractPropertiesVariants(classId, request, null, 0.1);

Возвращает объект OwnList<ExtractPropertiesResults>.

Настройки онтологии

Для чтения и изменения доступны следующие настройки онтологии:

  • Использование составных токенов для определения класса векторной моделью

Ontology.Bigrams //тип bool

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

  • Использование составных токенов для выделения свойств

Ontology.PropsBigrams //тип bool

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

  • Взвешенные токены

//Показатель степени для взвешивания произведения координат по специфичности токена
//Коэффициент веса - отношение количества встреч токена в классе к общему количеству встреч
Ontology.СoordinatesWeightPower //тип double. По умолчанию 4
//Множитель влияния произведения координат составных токенов
Ontology.ComplexAddCoef //тип double. По умолчанию 0.5
  • Ограничение избытка вариантов для игнорирования порядка в не лучших узлах

Ontology.BestVariantsCountMulriplier //тип double. По умолчанию 10- Фильтрация классов токена, балл которых ниже доли от лучшего варианта Ontology.BestPartTreshold //тип double. По умолчанию 0.2
  • Максимальное количество токенов шума внутри свойства

Ontology.MaxNoiseInsertion //тип int. По умолчанию 1
  • Максимально допустимое относительное отклонение для нечеткого поиска строковых некатегориальных признаков

Ontology.DlRel //тип double. По умолчанию 0.3
  • Максимально допустимое абсолютное отклонение для нечеткого поиска строковых некатегориальных признаков

Ontology.DlAbs //тип int. По умолчанию 3
  • Относительное окно для числовых значений, механика та же, через строки

Ontology.NumPart //тип double. По умолчанию 0.1
  • Степень уменьшения баллов соседних позиций на текущую

Ontology.PostitionRelax //тип double. По умолчанию 0.4
  • Множитель штрафа на модуль отклонения от исходного значения для упорядоченных числовых значений, край границы даст 0 вклад

Ontology.ContinuesPenalty //тип double. По умолчанию 1 / NumPart
  • Экспоненциальное сглаживание частот результатов нечеткого поиска при отклонении по ДЛ

Ontology.FuzzyRegr //тип doubleПо умолчанию 0.5
  • Использовать GreedyTabooSearch

Ontology.GreedTabooSearch, тип bool
  • Ограничение глубины поиска вариантов разбора свойств

Ontology.MaxSearchIteration, тип int, 0 - без ограничений, по умолчанию 5000 итераций.

Маппинг

При настройке маппинга в разделе Основные настройки указано имя переменной-источника и есть возможность вручную вписать выражение, которое при применении бизнес процесса будет передаваться в качестве значения для правой части.

../_images/image24.png

Кроме основных настроек, есть дополнительные, где можно выбрать способ добавления и заполнения элементов итогового массива.

Способ добавления элементов массива (addOption)

Варианты для выбора

Значение

Замена (Replace)

Количество записей в Массиве2 становится равным количеству записей Массива1.

Добавление (Add)

Количество записей в Массиве2 увеличивается на количество записей Массива1.

Способ заполнения элементов массива (параметр fillOption)

Варианты для выбора

Значение

С копированием (AutoMapping)

Содержимое из полей Массива1 копируется в соответствующие поля Массива2.

Без копирования (ManualMapping)

Содержимое соответствующих полей Массива2 остаётся пустым.

По умолчанию выбраны параметры замена с копированием. Пример того, как эти параметры работают: Дано два массива: Массив1 и Массив2:

../_images/image252.png

Результат сработавшего маппинга из Массива1 в Массив2 в зависимости от настроек:

../_images/image262.png

При маппинге немассив-немассив независимо от выбранных параметров маппинг всегда срабатывает по схеме Replace+AutoMapping.

Обработка архивной очереди

Работа с сообщениями, попавшими в архив, возможна из пользовательского интерфейса в ЦМ, а также программно с помощью шага Сервисный алгоритм в процессах. Исполнение кода сервисного алгоритма выполняется непосредственно на сервере и только с архивами, размещенными на этом сервере. Для работы с архивами реализован фасад ArchiveFacade.

Методы фасада ArchiveFacade доступные в шаге Сервисный алгоритм:

//Выполняет чтение всех сообщений архива. параметр count ограничивает количество
записей
OwnList<ArchiveObject> Select(int count = 200);
//Выполняет чтение всех сообщений архива с учетов фильтра filter
OwnList<ArchiveObject> Select(ArchiveOrTraceFilter filter);
//Удаляет из архива сообщение по переданному id объекта архива для указанного модуля
void Remove(Guid id, Guid moduleId);
//Удаляет из архива объекта архива для указанного модуля
void Remove(ArchiveObject archiveObject, Guid moduleId);
//Возвращает из архива сообщение в обработку по переданному id объекта архива для
указанного модуля. При передаче свойство в параметре prop, эти свойства добавляются к
свойствам сообщения
void Restore(Guid id, Guid moduleId, PropertiesCollection prop = null);
//Возвращает из архива объекта архива для указанного модуля. При передаче свойство в
параметре prop, эти свойства добавляются к свойствам сообщения
void Restore(ArchiveObject archiveObject, Guid moduleId, PropertiesCollection prop = null);
//Удалить все с фильтром по модулю
void Remove(Guid moduleId);
//Восстановить все с фильтром по модулю
void Restore(Guid moduleId);
//Удалить все с фильтром
void Remove(ArchiveOrTraceFilter filter);
//Восстановить все с фильтром
void Restore(ArchiveOrTraceFilter filter);
Для работы работы с методами фасада ArchiveFacade реализованы вспомогательные классы:
ArchiveObject - Запись архива, содержит информацию о событии размещения в архиве и
исходное сообщении. Поля объекта:
/// Данные записи архива - сообщение либо данные о БП
public RepositoryObject Data
/// Исходное сообщение
public InternalMessage OriginalMessage
/// Идентификатор модуля
public Guid TargetId
/// Источник сообщения
public Guid SourceId
/// Детали, информация об ошибках, описание сообщения
public string Details
/// Дата внесения в архив
public DateTime InsertDate
/// Позиция записи в архиве
public long Position
/// Тип события
public MessageEventType? EventType
// Receive, Send, Enqueue, Dequeue, PeekLock, AbandonPeekLock, CompletePeekLock,
DefineFunc, Drop, Error, Create, LiveTimeExpired, Transform, TransportError, Delay, Get,
TrRecv, TrSend, Sleep, Processing, Start, Finish, StartChild, FinishChild, IntSend, IntReceive,
Read, Write, Delete, Query, Archive, ReceiveAck, SendAck, Step, Route, RouteInt, Cancel
public Guid? StreamId
public string MessageType
public Guid? ProcessId
public Guid? TypeId
public Guid? InitialId

ArchiveOrTraceFilter - параметры для фильтрации данных архива:

public bool WithSnapshot
public string SnapshotId
public Guid? QueueId
public Guid? SourceId
public int Offset
public int Count = 200;
public DateTime? InsertDateStart
public DateTime? InsertDateEnd
public DateTime? CreationDateStart
public DateTime? CreationDateEnd
public Guid? MessageId
public Guid? StreamId
/// SourceId - Модуль
public string ModuleName
public string Operation
public string ProcessName
public string TypeName
/// InitialSourceId - Отправитель
public string SourceName
/// InitialSourceId - Отправитель
public List<Guid> SourceIds = new List<Guid>();
/// SourceId - Модуль
public List<Guid> ModulesIds = new List<Guid>();
public List<Guid> ProcessIds = new List<Guid>();
public List<Guid> TypeIds = new List<Guid>();
public List<string> Operations = new List<string>();
public bool WithBody
public MessageEventType? EventType

Примеры использования методов - Вывод в лог узла 10 сообщений. Результат: система выберет сообщения с самыми ранними датами вставки:

var list = ArchiveFacade.Select(10);
foreach(var l in list) { Logger.Info(l.Data.Id); }
  • Удалить сообщение по идентификатору:

ArchiveFacade.Remove(Guid.Parse("id сообщения"), Guid.Parse("id модуля"));
  • Отправить сообщение обратно в обработку с указанием свойства test:

var props = new PropertiesCollection();
props.AddValue("test", 12345);
ArchiveFacade.Restore(Guid.Parse("id сообщения"), Guid.Parse("id модуля"), props);
  • Использование фильтров:

var t = new ArchiveOrTraceFilter();
{
Count = 100, MessageId = Guid.Parse("2d8f628b-bc42-4196-87b8-72403e19a721"),
StreamId = Guid.Parse("d8c94648-c4cd-4dc5-80af-365c32689b04"),
};
var list = ArchiveFacade.Select(t);
foreach(var el in list)
{
Logger.Info(el.Data.Id);
Logger.Info(el.OriginalMessage);
Logger.Info(Encoding.UTF8.GetString(el.OriginalMessage.Body));
}

Правила обработки очередей

Для описания правил обработки очередей используется код C#. При использовании кода система предоставляет следующие возможности:

  • обращение к обрабатываемому сообщению с помощью переменной InitMessage и ее свойствам на вкладке Правило размещения;

  • вызов пользовательских программных модулей;

  • обращение к свойствам очередей, заданных на вкладке Основные, с помощью Queues;

  • использование логгера Logger.

Примечание

Изменение сообщения при размещении в очереди и извлечении из очереди не допускается!

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

  • название очереди;

public string Name { get; set; }
  • количество сообщений в очереди;

public int Count { get; set; }
  • размер очереди (находится в разработке);

public int Size { get; set; }
  • последняя добавление сообщения в очередь;

public DateTime LastInsert { get; set; }
  • последнее получение сообщения из очереди.

public DateTime LastTake { get; set; }

В Правиле размещения пользователь устанавливает в переменную Queue очередь, в которую должно быть помещено сообщение. Для написания алгоритма доступно использование свойств переменной InitMessage.Если значение не установлено, сообщение будет размещено в первой очереди списка. Пример Правила размещения по очередям в зависимости от размера сообщения:

if(InitMessage.BodyLength <= 100*1024 && Queues.Быстрая.Count<100)
{
Queue=Queues.Срочная; //Сообщение будет размещено в очереди Срочная
}
else
{
Queue=Queues.Обычная; //Сообщение будет размещено в очереди Обычная
}
// где Срочная и Обычная - Имена очередей в правиле

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

if (Queues.Срочная.Count > 0)
{
Queue = Queues.Срочная; //Сообщение будет извлечено из очереди Срочная, если она не
пустая
}
else if (Queues.Большие.Count > 0)
{
if (Queues.Обычная.Count == 0)
{
Queue = Queues.Большие; //Сообщение будет извлечено из очереди Большие, если
Обычная очередь пустая
}
else if (Queues.Обычная.LastTake == null ? true :
(Queues.Обычная.LastTake.Value.AddMinutes(10) < DateTime.Now))
{
Queue = Queues.Обычная; //Сообщение будет извлечено из очереди Обычная, если из нее
не выбирали более 10 минут
}
else
{
Queue = Queues.Большие;
}
}
else
{
Queue = Queues.Обычная;
}
../_images/image2710.png

Функции конвейера

Полный список функций фасада конвейера:

/// <summary>
/// Добавить сообщение для обработки в конвейер
/// </summary>
/// <param name="message"></param>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <returns></returns>
public Task Add(Message message, Guid conveyorId);
/// <summary>
/// Добавить сообщение для обработки в конвейер
/// </summary>
/// <param name="message"></param>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <returns></returns>
public Task Add(InternalMessage message, Guid conveyorId);
/// <summary>
/// Снимок очереди для обработки
/// </summary>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <returns></returns>
public Task<OwnList<ConveyorProcessData>> GetInputQueueSnapshot(Guid conveyorId);
/// <summary>
/// Текущие оперативные данные конвейера
/// </summary>
/// <param name="conveyorId"></param>
/// <returns></returns>
public Task<OwnList<ConveyorProcessData>> GetOperativeDataSnapshot(Guid
conveyorId);
/// <summary>
/// Результат работы конвейера
/// </summary>
/// <param name="Id">Идентификатор результата</param>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <returns></returns>
public Task<ConveyorProcessData> GetResult(Guid Id, Guid conveyorId);
/// <summary>
/// Результат работы конвейера
/// </summary>
/// <typeparam name="T">Тип результата</typeparam>
/// <param name="Id">Идентификатор записи</param>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <returns></returns>
public Task<T> GetResult<T>(Guid Id, Guid conveyorId) where T : BaseClass;
/// <summary>
/// Попытка получить результат операции
/// </summary>
/// <param name="Id">Идентификатор результата</param>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <param name="result">Результат</param>
/// <returns></returns>
public bool TryGetResult(Guid Id, Guid conveyorId, out ConveyorProcessData result);
/// <summary>
/// Попытка получить результат операции
/// </summary>
/// <typeparam name="T">Тип результата</typeparam>
/// <param name="Id">Идентификатор записи результата</param>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <param name="result">Результат</param>
/// <returns></returns>
public bool TryGetResult<T>(Guid Id, Guid conveyorId, out T result) where T : BaseClass;
/// <summary>
/// Все результаты работы конвейера
/// </summary>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <returns></returns>
public Task<OwnList<ConveyorProcessData>> GetConveyorResults(Guid conveyorId);
/// <summary>
/// Все результаты работы конвейера с типизацией
/// </summary>
/// <typeparam name="T">Тип в котором мы хотим получить результат</typeparam>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <returns></returns>
public Task<OwnList<T>> GetConveyorResults<T>(Guid conveyorId) where T : BaseClass;
/// <summary>
/// Список результатов работы конвейера
/// </summary>
/// <typeparam name="T">Ожидаемый тип данных</typeparam>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <param name="dataListType">Список, для определения типа данных</param>
/// <returns></returns>
Task<OwnList<T>> GetConveyorResults<T>(Guid conveyorId, OwnList<T> dataListType)
where T : BaseClass;
/// <summary>
/// Удалить результат работы конвейера
/// </summary>
/// <param name="Id">Идентификатор результата</param>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <returns></returns>
public Task DeleteResult(Guid Id, Guid conveyorId);
/// <summary>
/// Текущий стейт конвейера
/// </summary>
/// <param name="conveyorId">Идентификатор конвейера</param>
/// <returns></returns>
public ApplyState GetState(Guid conveyorId);

Функции хранилища сообщений

Доступ к хранилищу сообщений можно также получить с помощью методов, доступных в шаге Алгоритм, либо в других местах с возможностью редактирования кода (скрипты/алгоритмы трансформаций). - Запись сообщения и обновление сообщения.

bool Write(Message msg, bool waitResponse, int timeout);

Пример использования в шаге Алгоритм:

MessageStorage.Write(message, true);
  • Проверка существования записи в хранилище

bool Exists(Guid entityId);

Пример использования в шаге Алгоритм:

MessageStorage.Exists(entityId);
  • Получение сообщения

Message Get(Guid entityId);

Пример использования в шаге Алгоритм:

MessageStorage.Get(entityId);
  • Удаление сообщения

bool Delete(Message msg, bool waitResponse);

Пример использования в шаге Алгоритм:

MessageStorage.Delete(message, true);
  • Получение записей из хранилища запросом SQL

void Query<T>(string query, PropertiesCollection parameters, IList<T> resultList);

Пример использования в шаге Алгоритм:

var query = "SELECT TOP (10) ms.Object AS MyMessage FROM MessageStorage AS ms";
var result = new OwnList<InternalMessage>();
MessageStorage.Query(query, result);

Методы трансформации

Доступны следующие объекты:

  • Logger - для вывода данных в лог.

  • Все переменные с вкладки Переменные.

  • Взаимодействие с модулем хранения учетных данный через объект Credential. Доступны только методы получения данных (Get/Has). (Методы: 7.3.10 Credential).

  • Стандартная переменная OwnList<Metadata.Systems> Receivers - в нее перед выполнением записывается список получателей из переменной типа Сообщение с флагом Принимает сообщение процесса.

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

  • Список сообщений для отправки - доступен через методы /SetMessage/Get. Изначально пустой.

  • Всем получателям исходного сообщения, для которых не было установлено сообщение через SetMessage, будет отправлено оригинальное сообщение:

void SetMessage(Message message) - регистрирует сообщение в список отправки.
Если у message есть получатель, которого нет в изначальном списке Receivers - будет
исключение.
Если этот экземпляр сообщения уже был зарегистрирован - то повторно он не добавляется

Получение сообщений для определенных получателей (тех, которые были установлены через SetMessage):

OwnList<Message> GetArrayOfMessage(Metadata.Systems rec)
OwnList<Message> GetArrayOfMessage(List<Metadata.Systems> rec)
OwnList<Message> GetArrayOfMessage(string rec)
OwnList<Message> GetArrayOfMessage(List<string> rec)
OwnList<Message> GetArrayOfMessage(Guid rec)
OwnList<Message> GetArrayOfMessage(List<Guid> rec)

Пример скрипты исходящей трансформации:

Logger.Verbose(Сообщение);
// Сообщение.SetBody("wewe");
BaseClass body = Сообщение.GetBodyAsDataType();
switch(body)
{
case Номенклатура исходное:
{
foreach (var rec in Receivers)
{
Message m = new Message();
switch(rec.Name)
{
case "warehouse":
{
SM.nomenclature newbody = new SM.nomenclature();
newbody.descr = исходное.Название;
newbody.extKey = исходное.EntityId;
//m.SetBody(newbody);
Сообщение.SetBody(newbody);
break;
}
case "Trade":
{
SM.products newbody = new SM.products();
newbody.fullname = исходное.Название;
newbody.id = исходное.EntityId;
//m.SetBody(newbody);
Сообщение.SetBody(newbody);
break;
}
default:
continue;
}
//m.Receivers.Add(rec);
//SetMessage(m);
}
break;
}
case null:
break;
default:
break;
}
Logger.Verbose($"После трансформации: {Сообщение}");

Список методов для процессов и алгоритмов входящей и исходящей трансформаций:

void SetOutMessage(Message message)

Список методов для скрипта трансформации:

void SetMessage(Message message)

Проверка

Функция проверки выполняется для полей типов данных, добавленных из атрибутов с включенным параметром Проверка.

Функция доступна для следующих элементов:

  • Обработчики

  • Определение функции

  • Скрипты трансформаций

  • Программные модули

  • Функции

  • Алгоритмы процессов

Метод проверки:

bool Check(out CheckResult сheckResult)

сheckResult представляет собой класс, содержащий ключ имени поля (string) и соответствующий текст ошибок. Для одного поля может быть выбрано несколько функций, т.е. в текст ошибок для поля может быть добавлено несколько ошибок.

Пример алгоритма проверки функции:

Книга кн = new Книга();
кн.Автор = "Стивен Кинг";
bool rez = кн.Check(out CheckResult checkResult);
if (rez)
{
                Logger.Info("Все хорошо");
}
else
{
                Logger.Info($"Все плохо: {checkResult}");
}

Для вызова в пользовательских алгоритмах используется следующая команда:

CustomFunc.[Функция]