4. Конфигурирование сервера
СМЭВ QL сервер содержит два конфигурационных файла:
credentials.yaml - конфигурирует представление сервера
application.yaml - конфигурирует поведение сервера
Состав настроек credentials.yaml:
version: 1.0.0
system:
mnemonic: smev_ql_mnemonic
instance: smev_ql_instance
5. Язык и синтаксис
5.1. Моделирование
Для моделирования документного слоя данных в спецификации выбран язык разметки YAML.
5.2. Запросы и ответы
Для написания запросов, а также в качестве сериализатора ответов, спецификация определяет использование JSON.
6. Типизация
Фактические типы данных наследуют типы данных JSON (включая NULL):
string;
number;
object;
array;
boolean;
null.
6.1. Типы данных в модели и приведение типов
В описании модели допускается указание фактического типа данных атрибута ресурса вторым элементом массива type. Указание является опциональным, по умолчанию подразумевается неограниченный STRING.
Пример из описания модели:
fields:
id:
name: Идентификатор записи
type:
- number
- SHORT
length: 20
nullable: not NULL
key: PRIMARY
В качестве второго уточняющего типа следует применять типы НСУД:
STRING;
DOUBLE;
FLOAT;
BOOLEAN;
BYTE (не поддерживается на витрине);
BINARY;
BIG_DECIMAL (не поддерживается на витрине);
LONG;
INTEGER;
SHORT;
DATE;
TIME;
TIMESTAMP.
7. Моделирование данных
Модели данных описываются в формате YAML в папке проекта models согласно спецификации СМЭВ QL.
7.1. Структура базовой модели
Базовая модель должна ставиться впереди общего файла моделей, так как от ее алиасов наследуется элементы пользовательских моделей. Описание базовой модели данных в формате YAML имеет следующую структуру:
default_string: &ds
name: Строка
type:
- string
- STRING
length: 0
nullable: NULL
key: NONE
source: NONE
default_number: &dn
name: Число
type:
- integer
- INTEGER
length: 0
nullable: NULL
key: NONE
source: NONE
primary_key: &pk
name: Ключ
type:
- string
- STRING
length: 0
nullable: NULL
key: PRIMAY
source: NONE
base_model: &base_model
default_fields: &default_fields
7.2. Структура модели данных
Каждая модель представляет из себя YAML-файл, который должен быть соединен с базовой моделью для прохождения валидации.
Первый блок модели определяет ее мета-данные и атрибутивный состав.
Мета-данные и поля модели
resources:
# slots — техническое название модели, по нему производятся все связи
- slots: *base_model
# значение name — название модели на русском языке
name: Слоты
# fields — список полей модели
fields:
# список полей может включать перечень полей из default_fields
<<: *default_fields
# поля по-умолчанию наследуются от ds (default_string) из базовой модели
id: *ds
resource_id: *ds
# у поля может быть переопределен source (по-умолчанию у каждого поля источник всей модели)
type: *ds
source:
field: tag_type
age: *ds
source:
field: tag_age
visitTime: *ds
duration: *ds
status: *ds
create_ts: *ds
update_ts: *ds
update_ts: *ds
Второй блок модели описывает связи моделей друг с другом через ключи primary_key и foreign_key.
Ключи могут быть составными (описывается массивом), ключи не обязательно должны быть ключами из БД.
Связи имеют два типа:
belongs_to
has_many (один ко многим)
Связи модели
# Блок connections описывает связи модели (по названию) через явно указываемых два ключа
connections:
belongs_to:
- resource:
primary_key: [ id ]
foreign_key: [ resource_id ]
has_many:
- book:
primary_key: [ id ]
foreign_key: [ slot_id ]
- unaccessible_period:
primary_key: [ resource_id, type ]
foreign_key: [ resource_id, type ]
Блок ограничений и разрешений использования условий поиска.
Связи модели
# Блок conditions описывает ограничения и разрешения на использование условий поиска
conditions:
allowed: [id, name] # если заполнено, то поиск разрешен только по этим полям и полям с ключами
denied: [snils] # если заполнено, то поиск запрещен по этим ключам
always: # наличие условий в блоке always должно ко всем запросам ресурса добавлять эти условия, если указаны в запросе, то перетирать
- region: ["=", "77"]
- blocked: ["=", true]
Блок — extract, описывает названия source из которого нужно извлекать модель и ее таблицу.
Источники модели
extract:
source:
- name: prostore
table: misdm.slots
Источники по условиям
В блоке c указанием источника в модели допускается указание условий его выбора через блок conditions. Блок conditions содержит массив условий применения источника на основании значений полученных в запросе атрибутов:
extract:
source:
- name: prostore1
table: misdm.slots
conditions:
# попадание в промежуток
- range:
field: age
from: 0
to: 2
- eq:
field: color
not: "blue"
- name: prostore2
table: misdm.39slots
conditions:
# ограничения по (не)равенству
- eq:
field: resource_id
is: 1
- name: prostore3
table: misdm.39slots
conditions:
# ограничения по наличию в источнике
- eq:
field: snils
extract:
source: redis
table: default_table
key: resource_hashed_id
algorithm: md5
# select count(*) > 0 from offices.offices where resource_hashed_id = ?
# параметр: md5(snils)
is: true
- name: prostore_default
table: misdm.39slots
conditions:
- fallback: true
7.3. Загрузка
Модели данных считываются, валидируются и загружаются в память из папки models при запуске СМЭВ QL сервера.
По-умолчанию используется версия model, на которую ссылается symlink current, при его отсутствии по-умолчанию считается старшая версия.
Примечание
Модели и версии, начинающиеся с подчеркивания (_) НЕ загружаются, они находятся в стадии проектирования.
7.4. Guard-атрибуты
Для ограничения возможности получения некоторых атрибутов без предварительного предоставления их же (или дополнительных) значения, извлекающим необходимо определить атрибуты-ограничители в блоке guard.
Пример:
fields:
<<: *default_fields
first_name: *ds
last_name:
<<: *ds
guard: [last_name]
snils:
<<: *ds
guard: [last_name first_name snils]
В примере извлечение first_name не ограничивается. Для получения last_name фамилия должна быть передана в блоке conditions, а для получения snils в conditions должны присутствовать фамилия, имя и сам СНИЛС.
8. Запросы
Запросы к серверу выполняют методом POST и содержат в теле JSON-объект, состоящий из обязательных блоков:
Блок Credentials;
Блок Query;
Также пространстве методов server находятся методы, помогающие эксплуатации корректно конфигурировать хранилища данных относительно модели СМЭВ QL.
8.1. Блок Credentials
"credentials":{
"system":{
"mnemonic":"117bed7f-1c07-4079-a446-1161588db4e5",
"instance_id":"ccb4a88f-f44b-43e7-8a97-3e45c8345e90",
"user_id":"5ed38461-0907-486a-930a-7b443482932c"
},
"request":{
"id":"df5a0073-c6be-4d8c-8eb2-9b2f4188a429",
"sub_id":"0cdb59ce-224b-4118-8da1-c5ea08a5d955",
"name":"driver_data",
"purpose_id":"ed1170f1-3caa-4985-aa38-c9c5a190b770",
"audit":"false",
"audit_id":"fc1048fe-323d-4eeb-92df-5710b3d1d100",
"audit_token":"39e47aac-45d2-44c1-8c26-2d9b28b1703b"
},
"signature":{
"digest": null,
"signature": null
}
}
8.2. Блок Query
{
"query": {
"office": {
"conditions": {
"phone": "(347) 246-53-00"
},
"attributes": [
"id",
"phone",
"name"
],
"cabinet": {
"conditions": {
"available": true
},
"attributes": [
"number",
"name",
"seats"
],
"online_room": {
"conditions": {
"public": true,
"software": "zoom"
},
"attributes": [
"url"
]
},
"parking": {
"conditions": {
"free": true,
"available": true
},
"attributes": [
"number",
"floor"
]
}
}
}
}
}
8.2.1. Условия фильтрации Conditions
Объединение условий только по and (MVP)
Операции сравнения (op):
= (по умолчанию)
>
>=
<
<=
in
like (на перспективу)
Условия сравнения применимы к численным типам, датам, временам и таймштампам.
Варианты определения условий фильрации:
По равенству
{
"query": {
"office": {
"conditions": {
"phone": "(347) 246-53-00"
}
}
}
}
На основе сравнения, краткая запись
{
"query": {
"office": {
"conditions": {
"area": [">","130"]
}
}
}
}
На основе сравнения, полная запись
{
"query": {
"office": {
"conditions": {
"area": {
"op": ">",
"value": "130"
}
}
}
}
}
Комплексное условие
{
"query": {
"office": {
"conditions": {
"area": [">","130"],
"floor": ["in", [1, 2]]
}
}
}
}
OR (ИЛИ) в условиях
В conditions СМЭВ QL запроса поддерживается возможность указывать логический ИЛИ через зарезервированное слово or.
В блок or необходимо передать массив объектов, содержащих условия в свою очередь объединённые логическим И (AND).
Все условия, находящиеся на одном уровне с or группируются через логическое И (AND), как при обычном СМЭВ QL Запросе.
Пример:
"conditions": {
"lastname": "П",
"middlename": "И",
"birthdate": "2021-11-29 00:00:00",
"or": [
{
"vin": "в1"
},
{
"vin2": "в2",
"model": "bmw"
}
],
"fetch": {
"order": [["id", "ASC"], ["number", "DESC"]], // ASC default
"page": [2, 10] // limit 10 offset 10
}
}
Условия описанного выше запроса (без учета fetch) соберутся в следующую конструкцию:
...
WHERE
(lastname = 'П' AND middlename = 'И' AND birthdate = '2021-11-29 00:00:00')
OR
(vin ='в1')
OR
(vin2='в2' AND model = 'bmw')
...
8.2.2. Сортировка и пагинация
В блоке conditions опционально можно добавить блок fetch, в котором указывать условия сортировки и выбора страниц.
Пример блока:
"conditions": {
"lastname": "П",
"middlename": "И",
"birthdate": "2021-11-29 00:00:00",
"fetch": {
"order": [["id", "ASC"], ["number", "DESC"]], // ASC default
"page": [2, 10] // limit 10 offset 10
}
}
Если порядок сортировки не указан, то применяется ASC.
Если не указаны страницы, то по умолчанию всегда устанавливается первая страница с лимитом, равными параметру default блока pagination в файле конфигураций application.yaml.
Если запрашивается элементов на страницу больше, чем значение max, то должно использоваться дефолтное значение.
pagination:
default: 100 //количество элементов на странице по умолчанию
max: 1000 //максимальное количество элементов на странице
8.3. Эксплуатационные запросы
В пространстве методов server находятся методы, помогающие эксплуатации корректно конфигурировать хранилища данных относительно модели СМЭВ QL.
Метод возврата списка обязательных для создания индексов: GET server/indexes/required
В ответе должен возвращаться JSON с полями, используемыми в связях моделей (connections) и блоке conditions.allowed моделей, если они определены (conditions)
{
"server": {
"mnemonic": "#mnemonic",
"instance": "#instance"
},
"indexes": {
"connections": [{
"source": "#source_name2",
"table": "#table_name2",
"fields": ["#field_name1", "#field_name2"]
},
{
"source": "#source_name2",
"table": "#table_name2",
"fields": ["#field_name1", "#field_name2"]
}
],
"conditions": [{
"source": "#source_name2",
"table": "#table_name2",
"fields": ["#field_name1", "#field_name2"]
},
{
"source": "#source_name2",
"table": "#table_name2",
"fields": ["#field_name1", "#field_name2"]
}
]
}
}
9. Обработка запросов
9.1. Логирование мета-данных
У каждого запроса логируются данные из блока credentials в info и выше.
Формат строчки лога:
{
"level": "info",
"time": "2000-01-01T01:01:01.111Z",
"name": "#{smevql_server_name}.request",
"system": {
"mnemonic": "117bed7f-1c07-4079-a446-1161588db4e5",
"instance_id": "ccb4a88f-f44b-43e7-8a97-3e45c8345e90",
"user_id": "5ed38461-0907-486a-930a-7b443482932c"
},
"request": {
"id": "df5a0073-c6be-4d8c-8eb2-9b2f4188a429",
"sub_id": "0cdb59ce-224b-4118-8da1-c5ea08a5d955",
"name": "driver_data",
"purpose_id": "ed1170f1-3caa-4985-aa38-c9c5a190b770",
"audit": "false",
"audit_id": "fc1048fe-323d-4eeb-92df-5710b3d1d100",
"audit_token": "39e47aac-45d2-44c1-8c26-2d9b28b1703b"
}
}
Для каждого входящего запроса логируется каждый отправленный запрос к источнику:
{
"level": "info",
"time": "2000-01-01T01:01:01.111Z",
"name": "#{smevql_server_name}.request",
"system": {
"mnemonic": "117bed7f-1c07-4079-a446-1161588db4e5",
"instance_id": "ccb4a88f-f44b-43e7-8a97-3e45c8345e90",
"user_id": "5ed38461-0907-486a-930a-7b443482932c"
},
"request": {
"id": "df5a0073-c6be-4d8c-8eb2-9b2f4188a429",
"sub_id": "0cdb59ce-224b-4118-8da1-c5ea08a5d955",
"name": "driver_data",
"purpose_id": "ed1170f1-3caa-4985-aa38-c9c5a190b770",
"audit": "false",
"audit_id": "fc1048fe-323d-4eeb-92df-5710b3d1d100",
"audit_token": "39e47aac-45d2-44c1-8c26-2d9b28b1703b"
},
"source_request": {
"id": "1cdb59ce-224b-4118-8da1-c5ea08a5d955",
"source": "#{source_name}"
}
}
Передача идентификаторов:
source_request.id передается в queryId тела запроса в Простор.
В x-request-id передается склейка {request.id};{request.sub_id};{source_request.id}
Логирование ответа
{
"level": "info",
"time": "2000-01-01T01:01:01.111Z",
"name": "#{smevql_server_name}.response",
"system": {
"mnemonic": "117bed7f-1c07-4079-a446-1161588db4e5",
"instance_id": "ccb4a88f-f44b-43e7-8a97-3e45c8345e90",
"user_id": "5ed38461-0907-486a-930a-7b443482932c"
},
"request": {
"id": "df5a0073-c6be-4d8c-8eb2-9b2f4188a429",
"sub_id": "0cdb59ce-224b-4118-8da1-c5ea08a5d955",
"name": "driver_data",
"purpose_id": "ed1170f1-3caa-4985-aa38-c9c5a190b770",
"audit": "false",
"audit_id": "fc1048fe-323d-4eeb-92df-5710b3d1d100",
"audit_token": "39e47aac-45d2-44c1-8c26-2d9b28b1703b"
},
"source_request": {
"id": "1cdb59ce-224b-4118-8da1-c5ea08a5d955",
"source": "#{source_name}"
},
"response": {
"duration": "1ms",
"code": 200,
"result": "ok"
}
}
9.2. Построение плана
Входные данные:
загруженные модели, описывающие атрибутный состав сущностей, связи между сущностями и источники;
запрос поступивший к серверу.
Необходимо определить набор запросов и порядок их исполнения SMQEVQL сервером, обеспечить параллельное исполнение независимых запросов.
Вид плана запроса:
plan:
level: 1
- source: prostore1
query: SELECT id, phone, name FROM office WHERE phone = '(347) 246-53-00';
pk: id
alias: offices
level: 2
- source: prostore2
query: SELECT id, number, name, seats FROM cabinet WHERE office_id in (@offices) AND available = 'true';
pk: id
alias: cabinets
- source: prostore1
query: SELECT id, number, floor FROM parking WHERE office_id in (@offices) free = 'true' AND available = 'true';
pk: number, flor
alias: parkings
level: 3
- source: vostok7
query: SELECT url FROM online_room WHERE cabinet_id in (@cabinets) AND public = 'true' AND software = 'zoom';
pk: null
alias: online_rooms
Сначала параллельно выполняются запросы первого уровня, затем запрос второго уровня на основе данных полученных на первом уровне.
Фомирование плана запроса основывается на внешнем объединении данных в сторону основной сущности.
Порядок формирования плана запроса:
на основе query определяется основная запрашиваемая сущность;
на основе query определяются вспомогательные сущности;
на основе query определяются conditions к основной сущности;
на основе query определяются conditions к вспомогательным сущностям;
на первом уровне плана формируется запрос к основной сущности на основе: - запрошенных атрибутов; - данных модели; - условий фильтрации.
Отмечаются поля, составляющие PK.
Первичные ключи, даже отсутствующие в атрибутах запроса к серверу должны быть в запросе к источнику.
формируется запрос к вспомогательным сущностям на основе: - запрошенных атрибутов; - данных модели; - условий фильтрации; - с добавлением фильрации по PK основной или предшествующей сущности.
Первичные ключи, даже отсутствующие в атрибутах запроса к серверу должны быть в запросе к источнику, за исключением терминальных запросов.
План запроса соответсвует иерархии построенной от основной сущности на основе связей (modelconnections).
10. Ответы
Ответы СМЭВ QL сервера представляют из себя объект JSON, схема которого определяется составом запроса.
Например для запроса:
{
"query":{
"people":{
"conditions":{
"age":"<35"
},
"attributes":[
"name",
"phone",
"vsu_code"
],
"military_office":{
"attributes":[
"address"
]
}
}
},
"credentials":{
}
}
Ответ будет следующим:
{
"response":{
"people":[
{
"name":"Иван",
"phone":"+79011001010",
"vsu_code":"1025",
"military_office":[
{
"address":"г.Москва, ул.Угрешко"
}
]
},
{
"name":"Пётр",
"phone":"+79022002020",
"vsu_code":"1026",
"military_office":[
{
"address":"г.Москва, Хилков переулок"
}
]
}
]
},
"credentials":{
}
}
11. Стейт-машина СМЭВ QL
СМЭВ QL содержит встроенную машину состояний для изменения объектов модели внутри витрин данных. Одновременно с этим Стейт машина может, в качестве подтверждения перехода состояния, использовать внешний источник (например ИС Электронной очереди).
Карта состояний и переходов описывается в виде YAML-файла state.yaml располагаемого в папке states/<имя-модели>/<х.х версия модели> инстанса СМЭВ QL Сервера.
Описание формата и правил карты состояний:
model: slot # имя модели
states: # массив состояний объекта
- state: available # название состояния available
attributes: # массив атрибутов, описывающих состояние
- name: status # состояние определятся значением атрибута status
value: AVAILABLE # значение атрибута для описываемого состояния
initial: true
- state: booked
attributes:
- name: status
value: RECORDED
- state: reserved
attributes:
- name: status
value: RESERVED
- state: cancelled
attributes:
- name: status
value: CANCELED
- state: blocked
attributes:
- name: status
value: BLOCKED
events: # список событий изменения состояний, из них создаются методы API
- event: book # создает метод POST /states/slot/book
from: # массив состояний из которых возможен вызов события
- available
- reserved
to: booked # в какое состояние переводится объект после события
hooks: # массив связанных событий
- model: book # после перевода надо вызвать событие init для модели book
event: init
confirm:
source: rmis_rest # названия источника
endpoint: /booking/book
method: post
body: payload # что включать в тело запроса (full|state|conditions|payload|credentials)
accept: # условие принятия
jsonpath: $.status.statusCode
eq: 0 # ожидаем, что statusCode будет равен 0
- event: reserve
from: available
to: reserved
- event: block
from: available
to: blocked
- event: cancel
from:
- available
- reserved
- booked
- blocked
to: cancelled
hooks:
- model: book
event: cancel
При наличии заполненных состояний машины СМЭВ QL Сервер генерирует API c набором HTTP-методов, отвечающих за изменение и просмотр состояний объектов:
GET /states — получить карту переходов
GET /states/<model-name> — получить карту переходов конкретной модели
POST /states/<model-name>/<event-name> — выполнить переход состояний для модели
Запрос выполнения перехода:
POST /states/slot/book
{
"state": {
"conditions": {
"id": "d9e70331-b4c0-4e96-96b6-322ac75e5188" # slot_id
},
"payload": {
"bookId":"82dcac12-0a29-4fff-b9a7-8dfc84f7853d",
"patient_Id":"23453456",
"booking_type":"APPOINTMENT",
"caseNumber":"73367196",
"preliminaryReservation": false,
"email":"email@gmail.com",
"mobilePhone":"89150000102",
"referral_id":"102111",
"cards_id":"102"
}
},
"credentials": {
"system": {
"mnemonic": "117bed7f-1c07-4079-a446-1161588db4e5",
"instance_id": "ccb4a88f-f44b-43e7-8a97-3e45c8345e90",
"user_id": "5ed38461-0907-486a-930a-7b443482932c"
},
"request": {
"id": "df5a0073-c6be-4d8c-8eb2-9b2f4188a429",
"sub_id": "0cdb59ce-224b-4118-8da1-c5ea08a5d955",
"name": "request_name",
"purpose_id": "ed1170f1-3caa-4985-aa38-c9c5a190b770",
"audit": false,
"audit_id": "fc1048fe-323d-4eeb-92df-5710b3d1d100",
"audit_token": false
}
}
}
11.1. Спецификация интерфейса Стейт-машины
openapi: 3.0.0
x-stoplight:
id: 5i2oag6m5eq3v
info:
title: SmevQLStateMachine
version: '1.0'
description: ''
servers:
- url: 'http://localhost:3000'
paths:
/states:
parameters: []
get:
summary: Get models
tags: []
responses:
'200':
description: ''
content:
application/x-yaml:
schema:
$ref: '#/components/schemas/Models'
examples: {}
application/xml:
schema:
type: object
properties: {}
multipart/form-data:
schema:
type: object
properties: {}
text/html:
schema:
type: object
properties: {}
operationId: get-models
description: Retrieve the information of models
'/states/{model}':
parameters:
- schema:
type: string
name: model
in: path
required: true
get:
summary: Get model
tags: []
responses:
'200':
description: Model Found
content:
application/x-yaml:
schema:
$ref: '#/components/schemas/Model'
examples: {}
'400':
description: Bad Request
'404':
description: Model Not Found
operationId: get-model
description: Retrieve the information of model
parameters: []
'/states/{model}/{event}':
post:
summary: State change
operationId: post-state
responses:
'200':
description: State Updated
content:
plain/text:
schema:
type: string
examples: {}
'400':
description: Bad request
'404':
description: Not Found
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StateUpdate'
examples: {}
description: Post the necessary fields for the API to create a new user.
description: Update state
parameters: []
parameters:
- schema:
type: string
name: model
in: path
required: true
- schema:
type: string
name: event
in: path
required: true
components:
schemas:
State:
type: object
x-stoplight:
id: 89f55561cae04
properties:
state:
type: string
attributes:
type: array
minItems: 1
items:
$ref: '#/components/schemas/Attribute'
initial:
type: boolean
Model:
type: object
x-stoplight:
id: b96a73db1e1b2
properties:
model:
type: string
states:
type: array
minItems: 1
items:
$ref: '#/components/schemas/State'
events:
type: array
items:
$ref: '#/components/schemas/Event'
Events:
title: Events
x-stoplight:
id: qdvbkmgs9xkli
type: array
items:
$ref: '#/components/schemas/Event'
States:
$ref: '#/components/schemas/State'
x-stoplight:
id: wab1w6ro30nrl
Event:
title: Event
x-stoplight:
id: sr024y2v7khum
type: object
properties:
event:
type: string
from:
type: string
to:
type: string
Models:
title: ModelSet
x-stoplight:
id: e7de590d788a7
type: array
items:
$ref: '#/components/schemas/ModelInstance'
ModelInstance:
type: object
properties:
model:
type: string
states:
$ref: '#/components/schemas/States'
events:
$ref: '#/components/schemas/Events'
ModelSet:
type: array
items:
$ref: '#/components/schemas/Model'
Attribute:
title: Attribute
x-stoplight:
id: 3kiqu047734tc
type: object
properties:
name:
type: string
value:
type: string
description: ''
StateUpdate:
title: StateUpdate
x-stoplight:
id: 2iyfifo0q1dt2
type: object
properties:
state:
type: object
properties:
conditions:
type: object
payload:
type: object
credentials:
type: object
properties:
system:
type: object
properties:
mnemonic:
type: string
instance_id:
type: string
user_id:
type: string
request:
type: object
properties:
id:
type: string
format: uuid
sub_id:
type: string
format: uuid
name:
type: string
purpose_id:
type: string
format: uuid
audit:
type: boolean
audit_id:
type: string
format: uuid
audit_token:
type: string
Пример реализации: Спецификация интерфейса Стейт-машины РМИС (OpenAPI)
openapi: 3.0.0
x-stoplight:
id: 5i2oag6m5eq3v
info:
title: SmevQLStateMachine
version: '1.0'
description: ''
servers:
- url: 'http://localhost:3000'
paths:
/states:
parameters: []
get:
summary: Get models
tags: []
responses:
'200':
description: ''
content:
application/x-yaml:
schema:
$ref: '#/components/schemas/Models'
examples: {}
application/xml:
schema:
type: object
properties: {}
multipart/form-data:
schema:
type: object
properties: {}
text/html:
schema:
type: object
properties: {}
operationId: get-models
description: Retrieve the information of models
'/states/{model}':
parameters:
- schema:
type: string
name: model
in: path
required: true
get:
summary: Get model
tags: []
responses:
'200':
description: Model Found
content:
application/x-yaml:
schema:
$ref: '#/components/schemas/Model'
examples: {}
'400':
description: Bad Request
'404':
description: Model Not Found
operationId: get-model
description: Retrieve the information of model
parameters: []
'/states/{model}/{event}':
post:
summary: State change
operationId: post-state
responses:
'200':
description: State Updated
content:
plain/text:
schema:
type: string
examples: {}
'400':
description: Bad request
'404':
description: Not Found
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/StateUpdate'
examples: {}
description: Post the necessary fields for the API to create a new user.
description: Update state
parameters: []
parameters:
- schema:
type: string
name: model
in: path
required: true
- schema:
type: string
name: event
in: path
required: true
components:
schemas:
State:
type: object
x-stoplight:
id: 89f55561cae04
properties:
state:
type: string
attributes:
type: array
minItems: 1
items:
$ref: '#/components/schemas/Attribute'
initial:
type: boolean
Model:
type: object
x-stoplight:
id: b96a73db1e1b2
properties:
model:
type: string
states:
type: array
minItems: 1
items:
$ref: '#/components/schemas/State'
events:
type: array
items:
$ref: '#/components/schemas/Event'
Events:
title: Events
x-stoplight:
id: qdvbkmgs9xkli
type: array
items:
$ref: '#/components/schemas/Event'
States:
$ref: '#/components/schemas/State'
x-stoplight:
id: wab1w6ro30nrl
Event:
title: Event
x-stoplight:
id: sr024y2v7khum
type: object
properties:
event:
type: string
from:
type: string
to:
type: string
Models:
title: ModelSet
x-stoplight:
id: e7de590d788a7
type: array
items:
$ref: '#/components/schemas/ModelInstance'
ModelInstance:
type: object
properties:
model:
type: string
states:
$ref: '#/components/schemas/States'
events:
$ref: '#/components/schemas/Events'
ModelSet:
type: array
items:
$ref: '#/components/schemas/Model'
Attribute:
title: Attribute
x-stoplight:
id: 3kiqu047734tc
type: object
properties:
name:
type: string
value:
type: string
description: ''
StateUpdate:
title: StateUpdate
x-stoplight:
id: 2iyfifo0q1dt2
type: object
properties:
state:
type: object
properties:
conditions:
type: object
properties:
id:
type: string
format: uuid
payload:
type: object
properties:
book_id:
type: string
format: uuid
patient_id:
type: string
booking_type:
type: string
case_number:
type: string
preliminary_reservation:
type: boolean
email:
type: string
mobile_phone:
type: string
referral_id:
type: string
cards_id:
type: string
credentials:
type: object
properties:
system:
type: object
properties:
mnemonic:
type: string
instance_id:
type: string
user_id:
type: string
request:
type: object
properties:
id:
type: string
format: uuid
sub_id:
type: string
format: uuid
name:
type: string
purpose_id:
type: string
format: uuid
audit:
type: boolean
audit_id:
type: string
format: uuid
audit_token:
type: string
11.1.1. Выполнение операций обновления данных в витрине
Инсерты в витрину выполняются в порядке поступления запросов.
Каждый экземпляр СМЭВ QL сервера ведет нарастающий счетчик инсертов.
Каждый экземпляр СМЭВ QL сервера создает один поток управления дельтами, который выполняет:
Периодически (период конфигурируемая величина, по умолчанию 60 сек) проверяет значение счетчика числа инсертов, если значение счетчика более 0
Выполняет открытие и закрытие дельты с флагом immediate, ошибки открытия и закрытия дельты игнорируются. Попытка закрытия дельты выполняется независимо от успешности открытия дельты.
Обнуляет значение счетчика.
Периодически (период конфигурируемая величина, по умолчанию 30 мин)
Выполняет открытие и закрытие дельты с флагом immediate, ошибки открытия и закрытия дельты игнорируются. Попытка закрытия дельты выполняется независимо от успешности открытия дельты.
Чтение данных сервером СМЭВQL выполняется с применением AS OF <maxLong>.
11.1.2. Обновление объектов через Стейт-машину
Через Стейт-машину можно обновлять записи в витрине. Для этого при конфигурировании карты состояний необходимо
задать значение у event updatable: true.
При этом если требуется дать возможность обновлять только часть
атрибутов, то ограничить этот список можно перечислив атрибуты в массиве updatable_attributes.
- event: reserve
from: available
to: reserved
updatable: true // по умолчанию false для всех, кроме init, возможность изменять запись при переводе статуса
updatable_attributes: [] // массив атрибутов, которые можно обновлять, пустой — можно все
Данные для обновления будут браться из блока payload запроса на смену состояния.
Для события init такое конфигурирование не требуется - по умолчанию обновления разрешены для всех атрибутов из payload.
12. Ошибки
Ошибки выводятся в блоке response:
{
"response": {
"errors": [
{
"error": "Запрещен вывод атрибутов без переданного guard",
"code": "401"
}
]
},
"credentials": {
}
}
12.1. Базовые ошибки СМЭВ Ql
1ХХ Ошибки разбора запроса
101 Запрос не должен называться „errors“ — Неправильное название запроса „errors“
2ХХ Ошибки модели
201 Неизвестный атрибут — У ресурса не найден атрибут с соотв. именем
202 Неизвестный ресурс — Ресурс с соотв. именем не зарегистрирован в модели данных
203 Неизвестная связь — Не найдена связь между двумя ресурсами
204 Неправильная связь — Размеры ключей не соответствуют для соединения одного ресурса с другим
3ХХ Ошибки источников
301 Неизвестный источник — Не найдено описание источника данных с соотв. именем
302 Неизвестный адаптер — Не найден адаптер с соотв. именем
4ХХ Ошибки доступов и ограничений
401 Запрещен вывод атрибутов без переданного guard — Среди запрашиваемых атрибутов есть атрибут с невыполненными ограничениями в блоке guard (не переданы в запросе атрибуты из guard)
402 Недостаточно атрибутов для выбора источника — Среди атрибутов фильтрации нет атрибутов, необходимых для выбора источника
403 Запрещенные атрибуты для поиска — Среди атрибутов фильтрации есть атрибуты, указанные в блоке denied модели
404 Атрибуты для поиска не разрешены — Среди атрибутов фильтрации есть атрибуты, которые не указаны в разрешающем блоке allowed модели
405 Попытка переопределения фиксированных условий поиска — Среди атрибутов фильтрации есть атрибуты, которые пытаются переопределить фиксированные ограничения поиска в блоке always модели
9ХХ Прочие ошибки
901 Непредвиденная ошибка — Непредвиденная ошибка