Skip to content

SvSergeyev/nominator-public

Repository files navigation

Nominator

Сервис для генерации имен "по-умолчанию"
Текущая версия (2023.1.20.02) предусматривает возможность создания имен для объектов, создаваемых в:

  • дереве проекта,
  • библиотеке требований,
  • сервисе генерации имен,
  • сервисе виртуальных датчиков

Запуск приложения

java -jar -DPATH_TO_PROP=Path:\to\custom.properties Path:\to\app.jar

Используемые properties

Переменная Значение по-умолчанию Изменяемый Примечание
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, н реализация отличается от имеющейся сейчас у сервисов бенча.
Можно переделать на аналогичную, но для этого как-то подтянуть из артифактори джарник service-discovery-client, плюс в bench-core добавить упоминание клиента сервиса в ServiceDiscoveryAwareRemoteServicesConfig


API

Контейнерные элементы

Предварительное формирование имени контейнера

Все запросы на предварительное формирование имени отправляются при нажатии правой кнопкой в дереве и выборе команды "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": []
}

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

Обновление номера ревизии таргета происходит в двух случаях:

  1. при создании новой версии таргета (нажатие на кнопку Save на вкладке Value):
  • Request: PUT http://ip:port/classifier/target/{objectId}
    • {objectId} - идентификатор таргета, для которого создается новая версия;
  • Response: Http.status.200
  1. при нажатии на кнопку 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 - имя по-умолчанию для создаваемого файла собственной БД приложения. Схема таблиц БД и связей приведена ниже

Схема БД

Что нового

Версия 2023.1

DevOps

  • Переменная path.dictionaries.fn теперь должна указывать путь к папке (а не конкретному файлу), содержащей json-словари функционального номера;
  • Обновлена структура всех файлов словарей. Файлы необходимо обновить, актуальные версии - в папке /dictionary;
  • Добавлены новые json-словари для сервиса генерации имен виртуальных датчиков (4 шт.). Актуальные версии - в папке /dictionary/virtualsensor;
  • Добавлена переменная path.dictionaries.virtualsensor, указывающая путь к папке, содержащей json-словари генератора имен виртуальных датчиков;
  • В application.properties добавлена переменная services.properties.container.entity-index-length (int), определяющая количество символов в номере сущности при создании контейнерных элементов. Значение по умолчанию: 5.
  • Перед запуском приложения необходимо удалить старый файл БД;

API

  • Взаимодействие со словарем функционального номера:
    • Вместо 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

BE

  • Исправлена ошибка формирования номера сущности на текущем уровне (NNNN для объектов target library).
  • Добавлена новая логика формирования номера сущности на текущем уровне для проектов в общем дереве.
  • Добавлена логика определения состояния чекбокса "Включить классификатор" (в модальном окне создания объекта) как для контейнерных объектов, так и для объектов библиотеки ЦЗ

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages