Функции

Для настройки логики работы с данными в Платформе реализован раздел Обработка - Функции. Здесь вы можете создать, изменить или удалить:

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

  • Алгоритмы, в которых логика работы описывается кодом.

  • Программные модули, которые созданы для написания простейших общеиспользуемых функций. Их можно будет вызывать в коде алгоритма.

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

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

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

В алгоритме определения функции (входящей/исходящей трансформации), процессах

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

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

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

  • 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;

  • 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

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

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

Поле или переменная типа Ссылка представляет собой класс*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)

Метаданные

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

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

na mespace

enum name

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

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

Классификатор

M etadata

Class ifiers

Met adataInfo.Sea rchClassifier

Meta data.DataTypes GetDataType()

Тип данных

M etadata

Dat aTypes

M etadataInfo.S earchDataType

LinkType C reateLink(Guid entityId)

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

M etadata

Dy namics

MetadataInfo. SearchDynamic

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

M etadata

Enums

MetadataIn fo.SearchEnum

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

M etadata

SM

Metadata Info.SearchSM

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

M etadata

Fun ctions

M etadataInfo.S earchFunction

Система

M etadata

S ystems

MetadataInfo .SearchSystem

SystemInfo G etSystemInfo()

Роли

M etadata

Roles

MetadataIn fo.SearchRole

CredentialRole GetRoleInfo()

Обработчики

M etadata

Ha ndlers

HandlerInfo Ge tHandlerInfo()

Методы поиска возвращают соответствующее значение перечисления. Если не найдено, то возвращается значение 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.Dynamics Методы расширения для перечисления:

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() – возвращает объект роли (см. методы Credential)

Тип метаданных: Системные типы (метаданные) Перечисление: 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) – возвращает значение перечисления классификаторов по идентификатору
DynamicsExtensions.Dynamics 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/image162.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);

Работа с динамическими типами

dynamic GetDynamic(Guid typeId, Guid entityId);
dynamic GetDynamic(Guid typeId, string name);
OwnList<dynamic> GetListDynamic(Guid typeId);

void WriteDynamic(dynamic dynamicTypeObj);
void DeleteDynamic(Guid typeId, Guid entityId);
void DeleteDynamic(dynamic dynamicTypeObj);

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

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);

Примеры в наборе тестов Шаг записи в коде алгоритма http://srv-teamcity.axelot.local:8080/issue/DTT-42.

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

Создать роль в ЦН. Публикация данных -> Роли -> +

../_images/image172.png

Получить роли можно в 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 - роли.

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

Публикация данных -> Роли -> выбрать роль -> нажать на значок «Удалить».

../_images/image1810.png

При удалении роли из ЦУ удалятся записи в таблице 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/image1911.png

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

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

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

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

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

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

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

  • Поиск;

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

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

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

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

../_images/image225.png
../_images/image2310.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, properities);

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

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/image2411.png

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

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

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

Значение

Замена (Replace)

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

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

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

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

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

Значение

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

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

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

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

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

../_images/image255.png

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

../_images/image2611.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/image2711.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)