Библиотеки разработки
Для настройки логики работы с данными в Платформе реализован раздел Схемы обработки. Здесь вы можете создать, изменить или удалить следующие схемы обработки данных:
Бизнес-процессы, подпроцессы, маршруты, конвейеры, входящие и исходящие процессы трансформации, в которых логика работы создается схематично (ref:маршруты <route>), и есть возможность указать правило перехода в тот или иной блок. Заранее созданные процессы можно встраивать в текущий поцесс соответствующим шагом.
Алгоритмы, функции, входящие и исходящие алгоритмы трансформации, в которых логика работы описывается кодом.
Программные модули, которые создаются для написания простейших общеиспользуемых функций. Их можно вызывать в коде алгоритма.
Настройка схемы обработки данных заключается в заполнении основных параметров, установке переменных, создании схемы процесса или добавлении кода логики работы.
Сообщения и их свойства
Тип Сообщение
В алгоритме определения функции (входящей/исходящей трансформации), процессах обработки и алгоритмах доступ к сообщению выполняется через переменную типа Сообщения с установленным признаком Принимает сообщение процесса.
Предусловие: создана в процессе переменная типа Сообщение с именем ВхСообщ.
Свойства типа:
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) – возвращает значение перечисления систем по идентификатору
Программный модуль
Программные модули используются для написания простых общеиспользуемых функций.
Программный модуль можно создать в разделе Схемы обработки:
Для программного модуля доступна возможность загрузки подключаемых библиотек в виде бинарных файлов или архивов:
В коде программного модуля пишется код функций, например:
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
Откройте Swagger узла и найдите следующий метод:
POST/api/credential/externalUsers/users - Добавить пользователя
Заполните все необходимые данные, например:
{ "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 минуты. По истечении времени необходимо запросить снова открытый ключ.
Выполнить метод, указав идентификатор внешнего пользователя:
Get/api/credential/externalUsers/publicKey - Получить ключ для шифрования пароля Скопировать полученный ключ.
Выполнить метод, указав пароль и скопированный ключ:
Get/api/credential/externalUsers/users/test-encrypt - Тестовый метод шифрования данных
Выполнить метод, указав идентификатор внешнего пользователя и зашифрованный пароль:
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.
Данные поля не отображаются в центре настройки.
Заполнение сервисных полей:
1. DateTime created Заполняется текущей датой сервера на момент записи для запроса insert Пример, при выполнении шага Запись. Формат даты в UTC.
2. DateTime updated Заполняется тек датой сервера на момент записи для запроса insert или update.
При обновлении данных у типа, система заменила дату обновления:
guid version - заполняется из принятого сообщения в банк.
Получить значения системные полей можно при использовании шагов:
Получение Объекта;
Поиск;
Шаги запроса.
Пример получения значений системных полей:
синтаксис <ТипДанных>.<НазваниеСистемногоПоля>=“<дата>“
Шаг Поиск: в строке поиска написать Животные.Created :“2022-05-2406:22:23.1600000“. При выполнении шага Поиск система вернет ответ следующей структуры:
Утилиты
Утилиты по трансформации тела сообщения 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) // копирует свойства из переданной коллекции в текущую. Существующие перезапишутся, те, которых нет в переданной коллекции остаются
Онтология
Первичная настройка
Создать модуль онтологии, указать параметры подключения к СУБД.
Создать классификатор, указать ИД модуля онтологии.
Создать алгоритмы, вызывающие функции онтологии и отправляющие ответные сообщения с результатами.
Функции онтологии
Для выполнении любой функции онтологии сначала необходимо выбрать классификатор с помощью метода:
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 итераций.
Маппинг
При настройке маппинга в разделе Основные настройки указано имя переменной-источника и есть возможность вручную вписать выражение, которое при применении бизнес процесса будет передаваться в качестве значения для правой части.
Кроме основных настроек, есть дополнительные, где можно выбрать способ добавления и заполнения элементов итогового массива.
Способ добавления элементов массива (addOption)
Варианты для выбора |
Значение |
---|---|
Замена (Replace) |
Количество записей в Массиве2 становится равным количеству записей Массива1. |
Добавление (Add) |
Количество записей в Массиве2 увеличивается на количество записей Массива1. |
Способ заполнения элементов массива (параметр fillOption)
Варианты для выбора |
Значение |
---|---|
С копированием (AutoMapping) |
Содержимое из полей Массива1 копируется в соответствующие поля Массива2. |
Без копирования (ManualMapping) |
Содержимое соответствующих полей Массива2 остаётся пустым. |
По умолчанию выбраны параметры замена с копированием. Пример того, как эти параметры работают: Дано два массива: Массив1 и Массив2:
Результат сработавшего маппинга из Массива1 в Массив2 в зависимости от настроек:
При маппинге немассив-немассив независимо от выбранных параметров маппинг всегда срабатывает по схеме 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.Обычная;
}
Функции конвейера
Полный список функций фасада конвейера:
/// <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.[Функция]