Журнал технических изменений¶
Примечание
Ниже представлены технические изменения вышедших релизов. Краткий перечень изменений релизов отражен в новых функциях. Также см. информацию о важных изменениях.
Версия 2.8¶
Переименование индексов OpenSearch¶
Исключена возможная коллизия имен системных индексов, индексов бизнес-процессов и индексов реестров/справочников OpenSearch.
Имена индексов имеют следующий вид: prefix_default_некоеИмя
, где prefix
– значение параметра org.unidata.mdm.search.index.prefix
(по умолчанию default
).
Переименованы следующие индексы (приведен вид имени индекса для настроек по умолчанию):
default_default_audit
➔default_default_[audit]
- индекс аудита;default_default_model
➔default_default_[model]
- индекс модели данных;default_default_$model
➔default_default_$[model]
- индекс черновиков модели данных (сейчас не используется);default_default_draft
➔default_default_[draft]
- индекс всех черновиков всех типов (сейчас не имеет доступа ни через FE, ни через REST API BE);default_default_workflow
➔default_default_[workflow]
- общий индекс задач и процессов;default_default_wf_имяПроцесса
➔default_default_[wf]_имяПроцесса
- индекс задач и процессов для каждого отдельного бизнес-процесса.
Имена реестров и справочников теперь не могут содержать в своем имени следующие символы (ограничения добавлены на BE, на FE ограничения на имя уже есть и более строгие):
:, ", *, +, /, \, |, ?, #, >, <
- ограничения OpenSearch на имя индекса;[, ]
- зарезервированные символы для системных индексов,$
- зарезервированный символ для индексов с черновыми элементами – например,$entityName
хранит поисковые данные черновиков записей реестра с именемentityName
,.
- точка уже была ранее запрещена.
Имена бизнес-процессов теперь не могут содержать в своем имени следующие символы (ограничения добавлены на BE, на FE ограничения на имя уже есть и более строгие):
:, ", *, +, /, \, |, ?, #, >, <
- ограничения OpenSearch на имя индекса,.
- точка уже была ранее запрещена.
Изменения в операции reindexDataJob¶
Параметр "Проиндексировать черновики" переименован в "Проиндексировать черновики записей". Этот параметр индексирует черновики записей и их дочерних сущностей (связей и т.п.) в индексы черновиков выбранных реестров/справочников;
- Добавлены новые параметры:
"Проиндексировать черновики" – выполняет индексацию черновиков в индекс
default_default_[draft]
,"Проиндексировать модель данных" – выполняет индексацию модели данных в индекс
default_default_[model]
.
Инструкция по миграции данных в переименованных индексах¶
Все индексы (кроме аудита) можно перезаполнить поисковыми данными через операцию переиндексации данных со следующими настройками (Рисунок 1).
Выполните миграцию данных индекса аудита следующим образом (замените хост и порт своими):
Старый индекс аудита обновите следующим запросом: PUT http://localhost:9200/default_default_audit/_settings с телом:
{ "settings": { "index.blocks.write": true } }
Если BE после обновления не запускался или уже запускался, но вы не хотите сохранять новые данные в аудите (или их нет), то:
Удалите новый индекс, если BE после обновления уже запускался: DELETE http://localhost:9200/default_default_[audit]
Затем клонируйте индекс в новый: PUT http://localhost:9200/default_default_audit/_clone/default_default_[audit]
Обновите новый индекс следующим запросом: PUT http://localhost:9200/default_default_[audit]/_settings с телом:
{ "settings": { "index.blocks.write": false } }
Если BE после обновления уже запускался и вы хотите сохранить новые данные в аудите, то (этот способ может занять более длительное время при большом размере старого индекса):
Выполните запрос реиндекса записей старого индекса в новый: POST http://localhost:9200/_reindex с телом:
{ "source": { "index": "default_default_audit" }, "dest": { "index": "default_default_[audit]" } }
Удалите старые индексы с помощью следующих запросов:
DELETE http://localhost:9200/default_default_audit
DELETE http://localhost:9200/default_default_model
DELETE http://localhost:9200/default_default_$model
DELETE http://localhost:9200/default_default_draft
DELETE http://localhost:9200/default_default_workflow
DELETE http://localhost:9200/default_default_wf_*
Рисунок 1 – Настройки операции переиндексации данных
Параметр максимального количества выгружаемых записей¶
Добавлен новый параметр в backend.properties для операции экспорта экспорта справочников в XLSX: com.unidata.mdm.bulk.export.records.max.count = ${BULK_EXPORT_RECORDS_MAX_COUNT:50000}, который ограничивает количество записей под выгрузку для настройки под выделенные мощности. В случае попытки экспорта большего кол-ва записей - отображается ошибка.
Добавлен новый блок параметров для настройки операции экспорта в XLSX через UI.
Количество выгружаемых записей ограничивается параметром.
Выбор единиц измерения в карточке записи¶
Frontend:
TextAttributeField.tsx
теперь используется исключительно для текстовых атрибутов. Для числового атрибута созданNumberAttributeField.tsx
.В
NumberAttributeField.tsx
реализована обертка, выводящая селектор единицы измерения.simpleAttributeEditOrPreview
используется внутриnumberWithMeasurement
во избежание потери фокуса на селекторе единицы измерения при сменеisEditMode
.Использование
TextAttributeField
для отображения числовых атрибутов отмечено как deprecated. Такое использование будет ограничено в версии 6.11.
Атрибуты в карточке записи¶
Генерация сторов атрибутов происходит всегда независимо от их скрытия (конструктор
DataAttributeValueFactory
);Удалены лишние вызовы
addAttributeIfNotExists
, так как теперь все атрибуты должны существовать сразу после инициации карточки;При сохранении из
dataEntity
удаляются только скрытые атрибуты;Пустые атрибуты, которые были изменены, при сохранении приводятся к единому виду и отправляются на BE;
В
AbstractRecordEntityStore
добавлена опцияignoreDefaultValues
, так как дефолтные значения не должны отображаться в пакетной модификации;В
ModelCollection
добавлен методcommitCollection
. Используется при добавлении атрибута в коллекциюdataEntity
. Изменение коллекции дата-атрибутов не должно отслеживаться, так как атрибуты могут динамически добавляться, и это не должно влиять наdirty
уdataEntity
.
Обратная совместимость:
Поле
hidden
вRecordAbstractAttribute
отмечено как deprecated, вместо него необходимо использовать методsetHidden
и геттерisHidden
.
Frontend SDK¶
В компоненте
OptionList
свойствоmaxHeight
помечено как deprecated в пользуDropDown.maxHeight
.
Настройки таймаута заброшенных подключений¶
В файл backend.properties добавлены параметры, отвечающие за настройки таймаута заброшенных подключений к БД:
org.unidata.mdm.core.job.datasource.removeAbandonedTimeout
иorg.unidata.mdm.core.job.datasource.suspectTimeout
.
История замещения пользователей¶
Переименован endpoint
/v1/commercial-core/user-replacement/list
с методом POST на/v1/commercial-core/user-replacement/active
.Ранее поинт
/v1/commercial-core/user-replacement/history
возвращал записи, если пользователь имел все права на администрирование замещений пользователя. Теперь получение всех записей истории возможно при наличии прав на чтение на ресурс безопасности "Администрирование замещений пользователей". В противном случае будут возвращаться только те замещения, для которых текущий пользователь является замещающим/замещаемым/создателем замещения. Для редактирования замещения пользователь должен либо обладать правами на редактирование замещений, либо быть создателем этого замещения.
Изменение настроек создания связей¶
Теперь для запроса списка связей используется POST запрос
/dg/meta/relations/list
.Добавлен новый endpoint для получения модели связей с возможностью пагинации и сортировки по типам связей, а также с возможностью фильтрации -
/v1/dg/meta/relations/list
. Метод - POST.
Атрибуты связей¶
Реализована возможность добавлять атрибуты мета-связей, а также добавлять значения атрибутов при создании связей.
Пока еще не реализовано:
Экспорт/импорт актива с атрибутами связи, отображение атрибутов на графе и поиск по атрибутам связи.
Ограничение на изменение/удаление атрибутов связи в модели при наличии данных.
Технические изменения:
Сегмент потока выполнения [RELATION_DELETE_START]
org.unidata.dg.data.service.segments.relations.delete.RelationDeleteModboxExecutor
объявлен deprecated и будет удален в следующем релизе.Метод
org.unidata.dg.data.type.keys.RelationKeys.getRelationType()
объявлен deprecated и будет удален в следующем релизе. Необходимо использовать методorg.unidata.dg.data.type.keys.RelationKeys.getTypeName()
.Метод
org.unidata.dg.meta.type.model.instance.AssetTypeElement.getReferencedLookups()
объявлен deprecated и будет удален в следующем релизе. Необходимо использовать методorg.unidata.dg.meta.type.model.instance.DataGovernanceEntityElement.getReferencedLookups()
.
Отображение информации о пользователе и заместителях¶
Существующий endpoint
/v1/commercial-core/user-replacement/load
с методом GET помечен как deprecated. Вместо него необходимо использовать новый point/v1/commercial-core/user-replacement/list
с методом POST.Добавлены новые поля в модель Substitution: user и replacedUser.
Добавлен
SearchSubstitutionListOp
вSubstitutionService
для получения списка заместителей для определенного пользователя.Добавлен
SpecificSubstitutionsStore
для обработкиSearchSubstitutionListOp
, так как при использованииSubstitutionsStore
вместе с заместителями подгружается и список всех пользователей, что негативно влияет на скорость загрузки.Добавлены точки расширения:
UserViewTooltipExtraContent
иUserViewContent
. Для них реализованыsubstitutionUserViewTooltip
иsubstitutionUser
соответственно.Добавлен чекбокс для UserView
showExtraData
, который отключает отображение информации о заменяющем, даже если таковой имеется.
Шифрование паролей подключений LDAP¶
Класс org.unidata.mdm.core.util.CryptUtils
объявлен deprecated. Необходимо использовать класс org.unidata.mdm.system.utils.CryptUtils
.
Шифрование паролей подключений LDAP переведено на общий механизм платформы. Если шифрование в платформе выключено, подключения LDAP шифроваться не будут.
Старые настройки подключений LDAP после обновления станут неактуальны. Для существующих подключений необходимо заново ввести пароль.
Оптимизация механизма истории запусков сканеров¶
Результаты старых запусков после обновления станут недоступны.
Добавлен новый сегмент org.unidata.dg.data[ASSET_DELETE_SNAPSHOT] для потока выполнения org.unidata.dg.data[ASSET_DELETE_START].
Добавлен новый сегмент org.unidata.dg.data[RELATION_DELETE_SNAPSHOT] для потока выполнения org.unidata.dg.data[RELATION_DELETE_START].
Доработка моделей краулеров и объектов физического слоя¶
Методы
getNested()
иgetNesteds()
классаorg.unidata.dg.meta.type.model.instance.DataGovernanceModelInstance
стали Deprecated.Методы
withNesteds(DataGovernanceNestedEntitySource...)
,withNesteds(Collection<DataGovernanceNestedEntitySource>)
класса org.unidata.dg.meta.type.model.source.DataGovernanceModel
стали Deprecated.После обновления модель типов активов может стать невалидной, если в ней присутствуют типы активов бизнес-слоя (созданные пользователем без тега
layer:physical
), наследованные от типов активов физического слоя. Чтобы избавиться от наследования бизнес-слоя от физического, рекомендуется воспользоваться импортом модели типов активов через xml (через UI нельзя изменять родительский тип актива). См. подробнее принцип валидации и объединения моделей.
Валидация длины строки атрибута¶
Добавлена валидация на длину строки атрибутов актива. Теперь нельзя опубликовать запись актива в котором присутствуют атрибуты с длиной строки больше 32 767 символов, так как это ограничение ячейки xlsx.
Для простых атрибутов просто сравнивается длина строки.
Для массив атрибутов сумма длин строк каждого значения массива, например, если в массиве есть элемент с длиной строки 32 767, то при добавлении элемента с длиной строки 1, черновик не опубликуется, так как массив атрибут при экспорте в xlsx записывается в одну ячейку.
Для комплексных атрибутов проверяются все вложенные атрибуты по правилам описанным выше.
Скрытые символы, например, перенос строки или абзаца, тоже считаются в общее количество символов (для кириллицы и латиницы), поэтому может не проходить валидация. Такое поведение считается корректным, т.к. эти символы тоже существуют в xlsx и могут поломать ячейку.
Настройка замещений пользователей¶
Метод ReadSubstitutionListOp
отмечен как deprecated, вместо него необходимо использовать метод ReadSubstitutionHistoryOp
.
Версия 2.7
Версия 2.7.1
Шифрование паролей подключений LDAP
Класс org.unidata.mdm.core.util.CryptUtils
объявлен deprecated. Необходимо использовать класс org.unidata.mdm.system.utils.CryptUtils
.
Шифрование паролей подключений LDAP переведено на общий механизм платформы. Если шифрование в платформе выключено, подключения LDAP шифроваться не будут.
Старые настройки подключений LDAP после обновления станут неактуальны. Для существующих подключений необходимо заново ввести пароль.
Версия 2.7
Отображение удаленных связей
На эндпоинтах
/v1/dg/data/relations
и/v1/dg/data/catalog/next-level
добавлен флаг "cascaded", еслиincludeInactive=true
иcascaded=true
, то возвращаются все активные и логически удаленные каскадно связи.На эндпоинте
/v1/dg/data/catalog/next-level
также добавлена поддержка флага "includeInactive" (работает так же, как и в/v1/dg/data/relations
).
Удаление информационной системы
Реализован новый эндпоинт для получения информации о наличии связей с бизнес-слоем или активами другой информационной системы: GET-запрос
/dg/meta/information-systems/has-relations
с Query-параметром "informationSystem": "Название ИС".
Очистка информационной системы
Реализован новый endpoint для очистки ИС с выбором сканера. url:
v1/data/clean/crawler-instance/
, method: DELETE, params: informationSystemName: Название ИС, crawlerInstanceName: Название сканера (на BE - имя crawler instance в моделиorg.unidata.mdm.meta.configuration.Descriptors.SOURCE_SYSTEMS
).
Ресурс безопасности на пользовательские пакетные операции
POST
/api/v2/core/import-data
POST
/api/v2/bulk-operations/execute
При отсутствии прав ответ: 403 У пользователя [user1] недостаточно прав для (импорта/экспорта/удаления - в зависимости от выбранной операции) активов. Доступ запрещен.
Кастомный модуль по поддержке SSO Kerberos
Добавлена возможность добавить кнопку Вход по ССО, для этого необходимо добавить параметр "SSO_BUTTON_ENABLED" : true" в customer json
Изменены параметры файла backend.properties:
com.universe.mdm.sso.kerberos.realm.name=${SSO_KERBEROS_REALM_NAME:USE.ME} //edit with correct domain name
com.universe.mdm.sso.kerberos.keytab.file=${SSO_KERBEROS_KEYTAB_FILE:${unidata.conf}/tomcat.keytab}
com.universe.mdm.sso.kerberos.service.principal=${SSO_KERBEROS_SERVICE_PRINCIPAL:HTTP/dmitrova.use.me@USE.ME}
Поддержка файловых массив-атрибутов
org.unidata.mdm.rest.system.upload.attachment.directory
org.unidata.mdm.rest.system.upload.attachment.memory.threshold
org.unidata.mdm.rest.system.upload.attachment.max.size
Были изменены на:
org.unidata.mdm.core.upload.attachment.directory
org.unidata.mdm.core.upload.attachment.memory.threshold
org.unidata.mdm.core.upload.attachment.max.size
Было добавлено поле:
org.unidata.mdm.core.file.max.count
Оно задает максимальное количество файлов для атрибута (по умолчанию 10).
Управление статусами вручную
Добавлена возможность ручного управления статусами объектов через REST. Подробнее см. в важных изменениях.
Метод
com.unidata.mdm.data.status.type.transition.DataStatusTransitionHandler.handle(List<DataStatusTransition>)
объявлен deprecated. Рекомендуется использовать вместо него методcom.unidata.mdm.data.status.type.transition.DataStatusTransitionHandler.after(List<DataStatusTransition>)
.
Сортировка записей активов без выбора конкретного актива
Добавлена индексация отображаемых имен активов и их типов, что позволяет выполнять поиск и сортировку по отображаемым именам.
В случае изменения типа актива будет необходимо выполнение переиндексации, о чем появится соответствующее сообщение в момент публикации типа актива.
Поддержка транслитерации в поиске
Для обновления необходимо установить плагин analysis-icu для OpenSearch.
Установка с Docker:
При запуске Universe DG из репозитория Docker через Docker Compose плагин будет установлен автоматически.
Важно: Перед запуском команды docker-compose up -d
необходимо убедиться, что присутствует файл opensearch-install-plugins-and-start.sh, который производит установку плагина analysis-icu, если она требуется, а также актуализирован файл docker-compose.yml:
...
opensearch-dg:
image: opensearchproject/opensearch:2.7.0
restart: always
environment:
- "OPENSEARCH_JAVA_OPTS=-Xms1024m -Xmx1024m"
- "discovery.type=single-node"
- "DISABLE_SECURITY_PLUGIN=true"
volumes:
- dg-opensearch-data:/usr/share/opensearch/data
- ./hunspell:/usr/share/opensearch/config/hunspell/
- ./opensearch-install-plugins-and-start.sh:/usr/share/opensearch/opensearch-install-plugins-and-start.sh
entrypoint: /usr/share/opensearch/opensearch-install-plugins-and-start.sh
...
Установка вручную:
Приведенные ниже команды выполняются из директории, где установлен OpenSearch.
Команда для проверки установленных плагинов:
bin/opensearch-plugin list
Команда для установки плагина analysis-icu:
bin/opensearch-plugin install analysis-icu
Пример команды для установки плагина оффлайн (необходимо заранее скачать zip-файл с плагином, например, по ссылке https://artifacts.opensearch.org/releases/plugins/analysis-icu/2.7.0/analysis-icu-2.7.0.zip):
bin/opensearch-plugin install file:C:/Downloads/analysis-icu-2.7.0.zip
Пример команды для установки плагина через указание URL на zip-файл с плагином:
bin/opensearch-plugin install https://artifacts.opensearch.org/releases/plugins/analysis-icu/2.7.0/analysis-icu-2.7.0.zip
История изменения актива
Доработан способ получения истории изменений записи актива.
Для сохранения дополнительных элементов истории, которые ранее никак не фиксировались (восстановление/удаление актива), создана таблица org_unidata_dg_data.transitions
. Также доступна регистрация новых типов transition'ов и их сохранение в таблицу.
Для различных потоков выполнения восстановления и удаления актива добавлены новые сегменты, которые сохраняют информацию об изменениях в org_unidata_dg_data.transitions (org.unidata.dg.data[ASSET_DELETE_TRANSITION], org.unidata.dg.data[ASSET_RESTORE_TRANSITION])
.
Получение истории записи вынесено в отдельный поток выполнения:
{
"startId": "org.unidata.dg.data[ASSET_HISTORY_START]",
"subjectId": "",
"description": "org.unidata.dg.data.asset.history.start.description",
"segments": [
{
"segmentType": "START",
"id": "org.unidata.dg.data[ASSET_HISTORY_START]"
},
{
"segmentType": "POINT",
"id": "org.unidata.dg.data[ASSET_HISTORY]"
},
{
"segmentType": "POINT",
"id": "org.unidata.dg.data[ASSET_HISTORY_TRANSITIONS]"
},
{
"segmentType": "FINISH",
"id": "org.unidata.dg.data[ASSET_HISTORY_FINISH]"
}
]
}
Добавлены новые эндпоинты:
GET-запрос
/v1/dg/data/assets-history/types
для получения всех типов событий истории актива.POST-запрос
/v1/dg/data/assets-history
для получения истории записи.
Примечания:
Эндпоинт для получения истории записи актива стал Deprecated - POST-запрос
/v1/dg/data/assets/vistory
Метод
org.unidata.dg.data.service.AssetsService.getVistory(AssetVistoryGetContext)
стал DeprecatedТочки пайплайна
org.unidata.dg.data[ASSET_VISTORY_GET_START]
,org.unidata.dg.data[ASSET_GET_VISTORY]
иorg.unidata.dg.data[ASSET_VISTORY_GET_FINISH]
стали Deprecated
Обновление OrientDB с версии 3.2.4 до 3.2.23
Добавлено свойство в backend.properties c названием БД OrientDB:
org.unidata.mdm.graph.storage.orientdb.datasource.database=dg
Изменено значение для свойства
org.unidata.mdm.graph.storage.orientdb.datasource.url
Было:
org.unidata.mdm.graph.storage.orientdb.datasource.url=remote:localhost:2424/dg
Стало:
org.unidata.mdm.graph.storage.orientdb.datasource.url=remote:localhost:2424
В url необходимо указывать только хост и порт для подключения к OrientDB.
Выбор формата импорта ФИО из Active Directory
Добавлен REST эндпоинт
Запрос: GET http://{{server}}:{{port}}/universe-backend/api/v1/ldap/configuration/name-formats
Ответ (displayName локализован):
{"details":{"info":[],"warning":[],"error":[]},
"names":[
{"name":"LAST_FIRST_MIDDLE","displayName":"фамилия / имя / отчество"},
{"name":"LAST_MIDDLE_FIRST","displayName":"фамилия / отчество / имя"},
{"name":"FIRST_LAST_MIDDLE","displayName":"имя / фамилия / отчество"},
{"name":"FIRST_MIDDLE_LAST","displayName":"имя / отчество / фамилия"},
{"name":"FIRST_LAST","displayName":"имя / фамилия"},
{"name":"LAST_FIRST","displayName":"фамилия / имя"},
{"name":"MIDDLE_LAST_FIRST","displayName":"отчество / фамилия / имя"},
{"name":"MIDDLE_FIRST_LAST","displayName":"отчество / имя / фамилия"}]}
Изменен объект для GET/POST/PUT http://{{server}}:{{port}}/unidata-backend/api/v1/ldap/configuration/{{_int}}
В объект
domains
добавлено поле "adUserNameFormat" типа строка. Значение - одно из списка name-formats
Версия 2.6
Работа с задачами
Для задач на backend добавлено поле "Инициатор". Для задач, созданных в более ранних версиях, поле будет отсутствовать в индексе - потребуется переиндексация бизнес-процессов (операция будет доступна в следующих релизах).
Комментирование задач
Удален сервис для работы с комментариями
com.unidata.mdm.worfklow.core.service.WorkflowCommentsService
.Удалено REST API для работы с комментариями БП (эндпоинты
/v2/workflow/core/comment
)При обновлении системы будет выполнена миграция, которая перенесет старые комментарии в модуль marks.
SSO
Поддержан кастомный header в запросах "Single-Sign-On"
При получении пустых логина и пароля не будет возвращена ошибка, если пользователь уже аутентифицирован и аутентификация могла быть проверена с помощью одного из AuthenticationProvider в имеющихся SecurityDataSource.
Переиндексация бизнес-процессов
Добавлены методы для массовой индексации в WorkflowIndexingComponent.
Добавлены методы для конвертации Camunda объектов в Workflow[Process|Task|Attachment|Comment]Converter.
Клонирование записей справочника
Добавлена новая точка расширения
DgCloneRecordParameters
.
Физический слой данных
Эндпоинт для удаления/очистки информационных систем (ИС) был изменен на
/dg/data/clean/information-system
с параметрамиinformationSystemName
(название ИС) иdrop
(булевое значение: false - очистка ИС, true - очистка и удаление ИС).
Последовательный запуск операций
Реализована возможность запуска новой операции после удачного/неуспешного завершения другой операции.
Запуск новой операции реализован с помощью TriggerExecutionListener.
В JobDefinitionStore имплементирован JobTriggersStore, реализующий настройку цепочек операций.
Добавлены API модули:
PUT /v2/core/jobs/triggers/{jobDefinitionId} - создание новой цепочки; сохранение идентификаторов связанных операций в таблице job_trigger.
GET /v2/core/jobs/triggers/{jobDefinitionId} - получение всех цепочек операций.
DELETE /v2/core/jobs/{jobDefinitionId}/triggers/{triggerId} - удаление цепочки операций.
Права доступа
Добавлены ресурсы:
Группы пользователей / User groups (вкладка Безопасность / Security).
Каталог доступа/ Access directory (вкладка Система / System).
Логаут заменен на возможность подтянуть обновления при обновлении групп пользователей.
Добавлен статус 401 Unauthorized:
В группе пользователей:
Если нет прав на чтение групп пользователей:
GET /v1/commercial-core/users-group/{groupName}/check-users
GET /v1/commercial-core/users-group/{groupName}
GET /v1/commercial-core/users-group/{groupName}/users
Если нет прав на редактирование групп пользователей:
POST /v1/commercial-core/users-group
PUT /v1/commercial-core/users-group/{groupName}
DELETE /v1/commercial-core/users-group/{groupName}
POST /v1/commercial-core/users-group/move
Каталог доступа:
Если нет прав к каталогу доступа:
POST /v1/ldap/configuration/sandbox
GET /v1/ldap/configuration
POST /v1/ldap/configuration
GET /v1/ldap/configuration/{id}
PUT /v1/ldap/configuration/{id}
DELETE /v1/ldap/configuration/{id}
POST /v1/ldap/configuration/preview
POST /v1/ldap/configuration/preview
Остались открытыми (чтобы у пользователя была возможность просмотреть свои группы в карточке):
GET /v1/commercial-core/users-group/by-user-login/{login}
GET /v1/commercial-core/users-group
Версия 2.5
Потоки выполнения
В поток выполнения [SCANNER_RESULT_START] добавлен новый сегмент [SCANNER_CLEAR_DELETED] типа Point, удаляющий активы и связи, которые ранее были удалены из сторонней информационной системы.
Удаление технических активов и связей выполняется после завершения загрузки данных краулером. В отчете работы краулера будет указано количество удаленных активов и связей (отчет доступен для просмотра в Уведомлениях системы).
Сегмент [SCANNER_CALCULATE_BREADCRUMBS] потока выполнения [SCANNER_RESULT_START] объявлен deprecated и будет удален в следующем релизе.
Граф связей
В org.unidata.mdm.graph.core.type.storage.GraphStorage
добавлен новый метод org.unidata.mdm.graph.core.result.GraphGetResult traverse(org.unidata.mdm.graph.core.context.GraphTraverseContext)
, который необходимо реализовать для всех кастомных графовых хранилищ.
Операция очистки паролей
Добавлена операция очистки паролей org.unidata.mdm.core.service.impl.job.CleanInactivePasswordsJob
. Параметры операции описаны по ссылке.
Конфигурация операции находится в org.unidata.mdm.core.configuration.CoreConfiguration
: cleanInactivePasswordsJobDetail и cleanInactivePasswordsJobTrigger.
В реализацию
org.unidata.mdm.core.service.impl.SecurityServiceImpl.login(AuthenticationRequestContext ctx)
включено разрешение на аутентификацию через сервисorg.unidata.mdm.core.service.AuthenticationAttemptCheckService
.В реализацию
org.unidata.mdm.core.service.impl.SecurityServiceImpl
добавлена зависимостьorg.unidata.mdm.core.service.AuthenticationAttemptCheckService
.
Реестр компонентов
Сервис interface org.unidata.mdm.core.service.AuthenticationAttemptCheckComponentRegister
Реестр компонентов AuthenticationAttemptCheckComponent - компоненты реализуют проверки права на аутентификацию.
Текущая реализация org.unidata.mdm.core.service.impl.security.AuthenticationAttemptCounterServiceImpl
реализует оба AuthenticationAttemptCheckService и AuthenticationAttemptCheckService.
Также реализация хранит лист компонентов. При регистрации компонента проверяет его наличие в списке и если не находит, то регистрирует и выводит в лог сообщение о регистрации с именем компонента. При удалении из типа актива нахождение не проверяется, но в лог пишется снятие с регистрации (даже если не был зарегистрирован).
Методы:
void register(AuthenticationAttemptCheckComponent component)
- добавляет компонент в реестр.void unregister(AuthenticationAttemptCheckComponent component)
- удаляет компонент из типа актива.
Ошибка о блокировке доступа
Ошибка: exception org.unidata.mdm.core.exception BlockedAuthenticationAttemptException extends PlatformBusinessException
.
В текущей реализации используется для UI сообщения пользователю о превышении лимита неудачных попыток аутентификации.
Примечание
На этом этапе пользователь обычно еще не авторизован, и получить его локаль может быть невозможно. Поэтому в конструкторе необходимо явно указывать локаль, в противном случае будет использоваться локаль системы, указанная в параметрах системы.
Класс для конкретных проверок
Класс abstract class org.unidata.mdm.core.service.AuthenticationAttemptCheckComponent implements AfterModuleStartup
реализует конкретную проверку и должен быть зарегистрирован в типе актива, чтобы участвовать при проверке разрешения на аутентификацию.
После старта модуля регистрируется в типе актива AuthenticationAttemptCheckComponentRegister автоматически, если включен (по методу isEnabled()).
Текущие реализации:
org.unidata.mdm.core.service.impl.security.UsernameAuthenticationAttemptCheckComponent
org.unidata.mdm.core.service.impl.security.ClientIpAuthenticationAttemptCheckComponent
Методы:
@Override public final void afterModuleStartup()
- регистрирует компонент в типе актива после старта модуля, если компонент включен.protected final void register()
- регистрирует компонент в типе актива.protected final void unregister()
- снимает регистрацию в типе актива.protected boolean isEnabled()
- включение компонента. По умолчанию возвращает true.public String getInternalComponentName()
- внутреннее имя компонента. По умолчанию возвращает полное имя класса. В текущей реализации используется только в методе getExternalComponentName по умолчанию.public String getExternalComponentName()
- возвращает внешнее имя компонента, например, более читаемое для лога. По умолчанию вызывает getInternalComponentName(). Например, "Username authentication attempt count check component" для UsernameAuthenticationAttemptCheckComponent.protected Locale locale(@NonNull AuthenticationRequestContext ctx)
- достает из контекста локаль, присылаемую пользователем при попытке аутентификации, чтобы использовать в локализации текстов. Например, ошибки о превышении лимита неудачных попыток аутентификации для IP адреса. Поскольку пользователь еще не авторизовался - TextUtils возвращает локаль системы иначе.public abstract boolean isAllowedToLogin(@NonNull AuthenticationRequestContext ctx)
- проверяет разрешение на аутентификацию согласно правилам компонента.public abstract void fail(@NonNull AuthenticationRequestContext ctx, Throwable cause) throws BlockedAuthenticationAttemptException
- действие при неудачной попытке аутентификации с указанием причины. Например, увеличить счетчик неудачных попыток. Может бросать BlockedAuthenticationAttemptException. Может не бросать исключение, если нет необходимости передавать наружу событие. Чтобы локализовать текст BlockedAuthenticationAttemptException можно использовать метод locale выше для выборки из контекста.public final void fail(@NonNull AuthenticationRequestContext ctx) throws BlockedAuthenticationAttemptException
- вызывает метод выше с cause = null.public abstract void success(@NonNull AuthenticationRequestContext ctx)
- действие при успешной аутентификации. Например, сбросить счетчики неудачных попыток.
Пример
Задача: необходимо добавить список разрешенных для аутентификации IP адресов.
Создайте реализацию AuthenticationAttemptCheckComponent.
Реализуйте
String getExternalComponentName()
- например, пусть возвращает "IP address white list authentication attempt check component".Добавьте туда список разрешенных адресов.
Реализуйте
isEnabled()
, если он не должен быть всегда включен.
Если включается/выключается в рантайме, то необходимо сделать метод, вызывающий register()/unregister().
Реализуйте
boolean isAllowedToLogin(@NonNull AuthenticationRequestContext ctx)
- проверьте, находится ли CLIENT_IP из AuthenticationRequestContext в списке разрешенных адресов.Реализуйте
fail(@NonNull AuthenticationRequestContext ctx, Throwable cause)
- в этом случае можно ничего не делать или написать в лог.Реализуйте
void success(@NonNull AuthenticationRequestContext ctx)
- в этом случае можно ничего не делать.
Подсчет количества неудачных попыток
Класс class org.unidata.mdm.core.type.security.AuthenticationAttempt implements Serializable
хранит информацию о количестве неудачных попыток и времени последней неудачной попытки.
Используется для компонентов проверки, которые реализуют счетчики попыток, основанные, например, на Map<Object, AuthenticationAttempt>
.
Поля класса:
public static final AuthenticationAttempt EMPTY = new AuthenticationAttempt(0, LocalDateTime.MIN)
- возвращать, если в истории нет неудачных попыток аутентификации, чтобы не возвращался null.
Поля объекта:
private final int tries
- количество неудачных попыток.private final LocalDateTime lastTime
- время последней попытки.
Методы:
public AuthenticationAttempt(int tries, @NonNull LocalDateTime last)
- конструктор.public int getTries()
- возвращает tries .@NonNull public LocalDateTime getLastTime()
- возвращает lastTime.@Override public String toString()
- возвращает "LoginAttempt{" + "tries=" + tries + ", lastTime=" + lastTime + '}'.
Реализации кэша
interface org.unidata.mdm.core.service.AuthenticationAttemptCache
- кэш количества неудачных попыток аутентификации по определенному ключу, если их необходимо запоминать.
Методы:
@NonNull AuthenticationAttempt get(@NonNull Object key)
- получение AuthenticationAttempt по ключу. Должен возвращать AuthenticationAttempt.EMPTY, если для ключа ничего нет.
void put(@NonNull Object key, @NonNull AuthenticationAttempt attempt)
- кладет AuthenticationAttempt по ключу.
void remove(@NonNull Object key)
- удаляет AuthenticationAttempt для ключа, например, при удачной аутентификации для сброса истории неудачных попыток.
void clear(long ttlMinutes)
- очищает старые записи по TTL (в минутах) на основе AuthenticationAttempt.lastTime.
void clear()
- очищает кэш.
abstract class org.unidata.mdm.core.service.impl.security.AbstractMapBasedAuthenticationAttemptCache implements AuthenticationAttemptCache
- реализует кэш на основеMap<Object, AuthenticationAttempt>
.
Для hazelcast использование можно посмотреть в ClientIpAuthenticationAttemptCheckComponent или UsernameAuthenticationAttemptCheckComponent.
Абстрактные методы:
protected abstract Map<Object, AuthenticationAttempt> getMap()
- получить карту, для использования в других методах, например, чтобы достать из hazelcast
Методы:
@NonNull @Override public AuthenticationAttempt get(@NonNull Object key)
- по умолчаниюgetMap().getOrDefault(key, AuthenticationAttempt.EMPTY)
.
@Override public void put(@NonNull Object key, @NonNull AuthenticationAttempt attempt)
- по умолчаниюgetMap().put(key, attempt)
.
@Override public void remove(@NonNull Object key)
- по умолчаниюgetMap().remove(key)
.
@Override public void clear(long ttlMinutes)
- по умолчанию фильтрует и удаляет записи, у которых истекло время жизни. Для hazelcast нужно переписать, например, используяdestroy()
.
Предложения связей
Добавлены новые модули com.universe.dg.suggestions и com.universe.dg.rest.v1.suggestions для работы с предложениями связей. Подробную информацию о сервисах и примеры запросов см. по ссылке.
Комментарии и оценки карточки записи
Добавлен новый модуль org.universe.mdm.marks, позволяющий маркировать различные объекты системы. В текущей реализации модуль обслуживает функциональность оценок и комментариев карточки записи.
Комментарии и оценки присваиваются комбинации name space(register, asset, lookup, etc.), type name (имя сущности или "*" для всего пространства имен) и subject ID (идентификатор маркируемого объекта). Взаимодействие осуществляется через сервисы, позволяющие делать вставку, удаление и запросы к подсистемам. Также через сервисы происходит регистрация пользовательского кода на события добавления и удаления комментариев или оценок.
Оба сервиса реализуют 2 семейства операций: вставки и удаления, а также запросов - по namespace + typename (optional) + subject ID (идентификатор маркируемого объекта) и по ID(s) самого объекта комментария или оценки.
Комментарии:
Операция вставки всегда требует name space. Кроме режима like/dislike всегда требует subjectId. Наличие ID комментария обновляет объект комментария. Режим like/dislike не требует наличия subject ID.
Операция удаления всегда требует name space + subjectId или ID.
Сервис комментариев:
/**
* Comments service.
*/
public interface CommentsService {
/**
* Upserts a comment.
* @param ctx the upsert context
*/
void upsert(CommentUpsertContext ctx);
/**
* Deletes a comment or a number of comments.
* @param ctx the delete context
*/
void delete(CommentDeleteContext ctx);
/**
* Queries comments.
* @param ctx the context
* @return query result
*/
CommentQueryResult query(CommentQueryContext ctx);
/**
* Registers a lifecycle listener.
* @param ns the name space
* @param typeName the type name, may be null, "", or "*"
* @param listener the listener
*/
void register(NameSpace ns, String typeName, CommentLifecycleListener listener);
}
Оценки:
Операция вставки всегда требует name space. Кроме режима rescore всегда требует subjectId. Наличие ID оценки обновляет объект оценки. Режим rescore не требует наличия subject ID.
Операция удаления всегда требует name space + subjectId или ID.
Сервис оценок:
/**
* Score service.
*/
public interface ScoresService {
/**
* Upserts a score object.
* @param ctx the upsert context
*/
void upsert(ScoreUpsertContext ctx);
/**
* Deletes a score object or a number of score objects.
* @param ctx the delete context
*/
void delete(ScoreDeleteContext ctx);
/**
* Queries score objects.
* @param ctx the context
* @return query result
*/
ScoresQueryResult query(ScoreQueryContext ctx);
/**
* Registers a lifecycle listener.
* @param ns the name space
* @param typeName the type name, may be null, "", or "*"
* @param listener the listener
*/
void register(@Nonnull NameSpace ns, String typeName, @Nonnull ScoreLifecycleListener listener);
}