Сервис для генерации имен "по-умолчанию"
Текущая версия (2023.1.20.02) предусматривает возможность создания имен для объектов, создаваемых в:
- дереве проекта,
- библиотеке требований,
- сервисе генерации имен,
- сервисе виртуальных датчиков
- Запуск приложения
- Используемые properties
- API
- Используемые базы данных
- Что нового
java -jar -DPATH_TO_PROP=Path:\to\custom.properties Path:\to\app.jar
| Переменная | Значение по-умолчанию | Изменяемый | Примечание |
|---|---|---|---|
| spring.config.import | ${PATH_TO_PROP} | + | Путь к пользовательскому файлу свойств |
| server.port | 9000 | + | |
| application.name | name-classifier | - | |
| application.version | 2023.1.0 | - | |
| application.environment | dev | + | альтернативное значение application.environment='prod' |
| logging.file.name | - | + | путь к файлу лога |
| url.controller.prefix | /classifier | - | префикс по-умолчанию для всех запросов |
| eureka.client.enabled | false | + | взаимодействие с сервером eureka (service discovery) |
| eureka.client.serviceUrl.defaultZone | - | + | адрес сервера eureka |
| app.database.users.driver | org.postgresql.Driver | - | |
| app.database.users.username | + | имя пользователя для подключения к БД cml_core_db | |
| app.database.users.password | + | пароль для подключения к БД cml_core_db | |
| app.database.users.url | + | url БД cml_core_db | |
| app.database.users.prefix | jdbc:postgresql: | - | |
| app.database.users.dialect | org.hibernate.dialect.PostgreSQL10Dialect | - | |
| app.database.elements.driver | org.sqlite.JDBC | - | |
| app.database.elements.username | - | - | имя пользователя для подключения к собственной БД приложения |
| app.database.elements.password | - | - | пароль для подключения к собственной БД приложения |
| app.database.elements.prefix | jdbc:sqlite: | - | |
| app.database.elements.url | - | + | путь к файлу собственной БД приложения |
| app.database.elements.dialect | <..>/config.database.elements.SQLiteDialect | - | |
| path.dictionaries.fn | /etc/nominator-server/dict/fn | + | путь к папке, содержащей словари функционального номера |
| path.dictionaries.domain | /etc/nominator-server/dict/domain | + | путь к папке, содержащей словари генератора имен доменов |
| path.dictionaries.virtualsensor | /etc/nominator-server/dict/virtualsensor | + | путь к папке, содержащей словари генератора имен вирт. датчиков |
| app.database.targetlibrary.driver | org.postgresql.Driver | - | |
| app.database.targetlibrary.username | + | имя пользователя для подключения к БД cml_tl_db | |
| app.database.targetlibrary.password | + | пароль для подключения к БД cml_tl_db | |
| app.database.targetlibrary.url | + | url БД cml_tl_db | |
| app.database.targetlibrary.prefix | jdbc:postgresql: | - | |
| app.database.targetlibrary.dialect | org.hibernate.dialect.PostgreSQL10Dialect | - | |
| services.properties.container.entity-index-length | 5 | + | Количество символов в номере сущности на текущем уровне |
Все параметры, не имеющие значений по-умолчанию, должны быть переопределены в .properties-файле,
путь к которому указан в переменной PATH_TO_PROP (в противном случае приложение не запустится).
Формат пути на данный момент opt/nominator-server/... - без первого слеша
- Альтернативное значение application.environment=prod запрещает выполнение delete-запроса на http://app.ip/classifier/containertarget, который удаляет все записи из соответствующей таблицы
- Значение для app.database.users.url, если это IP, указывать именно в таком формате, с двумя слешами - //192...
- Изменение значения eureka.client.enabled на true требует указания адреса eureka-сервера в eureka.client.serviceUrl.defaultZone
Сервис отображается в service-discovery, н реализация отличается от имеющейся сейчас у сервисов бенча.
Можно переделать на аналогичную, но для этого как-то подтянуть из артифактори джарник service-discovery-client,
плюс в bench-core добавить упоминание клиента сервиса в ServiceDiscoveryAwareRemoteServicesConfig
Все запросы на предварительное формирование имени отправляются при нажатии правой кнопкой в дереве и выборе команды "Create..."
Request: POST http://ip:port/classifier/container/suggest
Body: ContainerSuggest
{
"type": "string",
"action": "suggest",
"uid": int,
"parent": {
"id": Integer,
"type": "string"
}
}
- type - тип создаваемого элемента ("folder", "loadcase"...);
- parent - IdentityData
- parent.id, parent.type - (nullable) идентификатор и тип родительской сущности;
- uid - идентификатор пользователя.
Response: ContainerOut + HttpStatus.201
{
"divisionCode": "string",
"productIndex": "string",
"analysisType": "string",
"numEntity": "string",
"type": "string",
"version": "string",
"classifierEnabled": boolean,
"classifierAvailable": boolean
}
- divisionCode - значение атрибута postalCode из AD соответствующего пользователя, "None" при отсутствии;
- productIndex - null для корневых элементов;
- analysisType - null для корневых элементов;
- type - форматированный тип создаваемого элемента (в соответствии с NamedObjectTypes);
- classifierEnabled - определяет, включен ли чекбокс (включена галочка или нет)
- classifierAvailable - определяет, доступен ли чекбокс для изменения пользователем (активен чекбокс или нет)
Request: POST http://ip:port/classifier/container
Body: ContainerCreate
{
"type": "string",
"action": "create",
"id": int,
"divisionCode": "string",
"productIndex": "string",
"analysisType": "string",
"parent": {
"id": Integer,
"type": "string"
}
}
- divisionCode, productIndex, analysisType, type - заполняются данными из ответа на suggest-запрос
- parent - null для корневых объектов в дереве 'Home environment'
Response: Http.status.200
Request: POST http://ip:port/classifier/target/suggest
Body: TargetSuggest
{
"type": "string",
"action": "suggest",
"parent": {
"id": Integer,
"type": "string"
}
}
- parent - IdentityData
- parent.id, parent.type - (nullable) идентификатор и тип родительской сущности;
- type - тип создаваемого элемента - "target" или "targetgtoup";
Response: TargetOut + HttpStatus.201
Объект TargetOut состоит из двух объектов - TargetShort + List
- TargetShort (json-поле target) для корневых элементов содержит значения полей по-умолчанию, для всех остальных будет содержать унаследованные от родительской сущности свойства
- List< CodeNamePair > (json-поле dict) представляет собой содержимое словаря, соответствующее унаследованному функциональному номеру создаваемой сущности
Например:
объект TargetOut для корневого элемента:
{
"target": {
"productIndex": null,
"fn": {},
"revision": "00" <or> null,
"numEntity": "0001",
"classifierEnabled": false,
"classifierAvailable": true <or> false
},
"dict": [
{
"code": "71",
"name": "Силовая установка"
},
...
{
"code": "80",
"name": "Система запуска двигателя"
}
]
}
- revision - null для targetgroup, '00' для target;
- dict - первый уровень словаря функционального номера, представленный в виде списка объектов класса CodeNamePair;
- classifierAvailable - для корневых элементов в общем дереве - false, в приватном дереве - true.
объект TargetOut для вложенного элемента, родительская сущность которого имеет функциональный номер 72-00:
{
"target": {
"productIndex": "string",
"fn": {
"AA": {
"code": "72",
"name": "Двигатель"
}
},
"revision": "00" <or> null,
"numEntity": "0001",
"classifierEnabled": true,
"classifierAvailable": false
},
"dict": [
{
"code": "10",
"name": "Редуктор, вал"
},
{
"code": "20",
"name": "Воздухозаборник"
},
...
{
"code": "00",
"name": "Общие сведения"
}
]
}
- fn - наследуемые от родительской сущности элементы функционального номера;
- dict - уровень словаря, соответствующий унаследованным элементам функционального номера
Наследование блоков функционального номера происходит по следующей схеме:
├─ Корневой элемент - может иметь любое количество заполненных блоков ФН
└─ I уровень вложенности - наследует блок 'AA' функционального номера корневого элемента
└─ II уровень - 'AA' корневого элемента + 'BB' элемента I уровня
└─ III уровень - 'AA' + 'BB' + 'CC' элемента II уровня
Элементы последующих уровней вложенности наследуют блоки ФН по схеме для III уровня
Request: POST http://ip:port/classifier/target
Body: TargetCreate
{
"type": "targetGroup" <or> "target",
"action": "create",
"id": int,
"productIndex": "string",
"fn": {
"AA": "XX",
"BB": "XX",
"CC": "XX",
"DD": "XX"
}
},
"name": "string",
"parent": {
"id": Integer,
"type": "string"
}
}
- id - objectId создаваемого объекта
- productIndex - заполняется данными из ответа на suggest-запрос;
- name, fn - формируется в пользовательской форме;
- "XX" - числовой код категории словаря. Заполняется в соответствии со значениями комбобоксов в пользовательской форме. При отсутствии значения поле может отсутствовать в запросе;
Response: Http.status.200
Request: POST http://ip:port/classifier/target/dic
Body: FunctionalNumberDictionaryRequest
{
"project": "string",
"fields": {
"aa": "string",
"bb": "string",
"cc": "string",
"dd": "string"
}
}
Response: TargetOut + Http.status.200
- TargetShort (json-поле target) содержит актуальный номер сущности на текущем уровне (numEntity)
- List< CodeNamePair > (json-поле dict)представляет собой содержимое словаря, соответствующее указанным параметрам ('aa', 'bb'...)
Поля в теле запроса необязательны, то есть:
- запрос с пустым телом
{}вернет список номеров проектов, для которых существуют словари функционального номера, а так же значение по-умолчанию номера сущности:
{
"target": {
"productIndex": null,
"fn": null,
"revision": null,
"numEntity": "0001"
},
"dict": [
{
"code": "105",
"name": "105"
},
{
"code": "P90",
"name": "П-90"
},
{
"code": "CD91",
"name": "ЦД-91"
}
]
}
- добавление полей в тело запроса возвращает соответствующий уровень словаря и уточненный номер сущности. Например, при наличии в проекте ЦД-91 двух ранее созданных объектов с функциональным номером '72-32', запрос с телом вида:
{
"project": "cd91",
"fields": {
"aa": "72",
"bb": "32"
}
}
возвращает содержимое блока "Двигатель — КВД" и '0003' для номера сущности:
{
"target": {
"productIndex": null,
"fn": null,
"revision": null,
"numEntity": "0003"
},
"dict": [
{
"code": "01",
"name": "Ротор"
},
{
"code": "02",
"name": "Статор"
}
{
"code": "03",
"name": "Подшипник"
}
]
}
- В случае, когда словарь для выбранных элементов пуст, сервис вернет пустой список и актуальный номер сущности:
{
"target": {
"productIndex": null,
"fn": null,
"revision": null,
"numEntity": "0001"
},
"dict": []
}
Обновление номера ревизии таргета происходит в двух случаях:
- при создании новой версии таргета (нажатие на кнопку Save на вкладке Value):
- Request: PUT
http://ip:port/classifier/target/{objectId}
- {objectId} - идентификатор таргета, для которого создается новая версия;
- Response: Http.status.200
- при нажатии на кнопку TargetLibrary в верхнем меню:
- Request: PUT
http://ip:port/classifier/target - Response: Http.status.200
Оба запроса работают. Предпочтительнее второй
Request: DELETE http://ip:port/classifier/{table}/{type}/{objectId}
- {table} - имя таблицы, из которой производится удаление - 'container', 'target'
- {type} - тип удаляемого элемента в соответствии с NamedObjectTypes
- {objectId} - идентификатор удаляемой сущности
Response: Http.status.204
Request: DELETE http://ip:port/classifier/{table}
Body: IdentityData
{
"id": Integer,
"type": "string"
}
- {type} - тип удаляемого элемента в соответствии с 'fullName' NamedObjectTypes
- {id} - идентификатор удаляемой сущности
Response: Http.status.204
Недоступно при
application.environment=prod
Request: DELETE http://ip:port/classifier/{table_name}/all
Response: Http.status.204
Request: GET http://ip:port/classifier/dic/domain?name={dictionary}
- dictionary - имя словаря. Должно соответствовать представленной ниже схеме:
| Параметр запроса | Соответствующий словарь | Файл словаря |
|---|---|---|
| node | Имена узлов | node.json |
| detail | Имена деталей | detail.json |
| domain | Тип домена | domain.json |
| surface | Тип поверхности | surface.json |
| rotation | Наличие вращения | rotation.json |
| location | Характеристика расположения | location.json |
| parameter | Тип параметра | parameter.json |
| index | Индексы | index.json |
Имена json-файлов словарей не менять, так как при парсинге словарей их названия берутся из названий файлов
Response: Http.status.200 + DomainDictionaryObject[]
Пример тела ответа для запроса на адрес /classifier/dic/domain?name=detail
[
{
"short":"AZ",
"full":"Аппарат закрутки"
},
{
"short":"OPK",
"full":"Обтекатель переходного канала"
},
...
{
"short":"BRN",
"full":"Подшипник"
}
]
Request: GET http://ip:port/classifier/dic/virtualSensor?name={dictionary}
- dictionary - имя словаря. Должно соответствовать представленной ниже схеме:
| Параметр запроса | Соответствующий словарь | Файл словаря |
|---|---|---|
| classificationGroups | Классификационная группа | classificationGroups.json |
| controlSection | Контрольная секция | controlSection.json |
| measuredParameter | Измеряемый параметр | measuredParameter.json |
| units | Единицы измерения | units.json |
Response: Http.status.200 + VirtualSensorDictionaryObject[]
Тело ответа на запрос аналогично ответу для генератора имен доменов
Request: GET http://ip:port/classifier
Response: Http.status.200 + текстовое сообщение, содержащее номер версии и значение переменной application.environment
Так же проверка статуса приложения доступна через запрос к service discovery
- cml_core_db - подключение только на чтение для доступа к значениям из таблиц users, approvals, approval_assignees
- cml_tl_db - подключение на чтение/запись для доступа к таблицам target и target_value
- nominatorDb.db - имя по-умолчанию для создаваемого файла собственной БД приложения. Схема таблиц БД и связей приведена ниже
- Переменная path.dictionaries.fn теперь должна указывать путь к папке (а не конкретному файлу), содержащей json-словари функционального номера;
- Обновлена структура всех файлов словарей. Файлы необходимо обновить, актуальные версии - в папке /dictionary;
- Добавлены новые json-словари для сервиса генерации имен виртуальных датчиков (4 шт.). Актуальные версии - в папке /dictionary/virtualsensor;
- Добавлена переменная path.dictionaries.virtualsensor, указывающая путь к папке, содержащей json-словари генератора имен виртуальных датчиков;
- В application.properties добавлена переменная services.properties.container.entity-index-length (int), определяющая количество символов в номере сущности при создании контейнерных элементов. Значение по умолчанию: 5.
- Перед запуском приложения необходимо удалить старый файл БД;
- Взаимодействие со словарем функционального номера:
- Вместо GET /target/dic?aa=AA&bb=BB&cc=CC&dd=DD теперь POST /target/dic c FunctionalNumberDictionaryRequest в теле;
- Добавлено API для взаимодействия со словарем генератора имен виртуальных датчиков:
- GET /dic/virtualSensor?name={dictionaryName}
- В ответ на suggest-запрос при создании контейнеров и таргетов добавлены поля classifierEnabled и classifierAvailable
- Исправлена ошибка формирования номера сущности на текущем уровне (NNNN для объектов target library).
- Добавлена новая логика формирования номера сущности на текущем уровне для проектов в общем дереве.
- Добавлена логика определения состояния чекбокса "Включить классификатор" (в модальном окне создания объекта) как для контейнерных объектов, так и для объектов библиотеки ЦЗ
