Services/Service-Registration.md
Назначение
Получать запрос на регистрацию ЮР лица, формирование набора sag, их отправка на выполнение и ожидания их выполнения, осуществление ответа на gateway по факту выполнения или ошибки выполнения запроса.
Структура БД, в которой буду хранится данные о saga-х
Таблица операций
| operation_uuid | operation_name | create_time | last_time_update |
|---|---|---|---|
| uuid | varchar(128) | timestamptz | timestamptz |
operation_uuid- уникальный id операции. Уникальноеoperation_name- имя операции.create_time- время создания операции.last_time_update- последние обновления, связанные с операцией.
Таблица описания sag
| saga_uuid | status | type | name | saga_data | operation_uuid |
|---|---|---|---|---|---|
| uuid | numeric(3) | numeric(3) | varchar(64) | json | uuid |
Статус имеет следующие значения:
0(undefined)10(created)20(in progress)30(completed)40(fallback in process)50(fallback completed)250(fallback error)255(error)
Поле type - указывает на тип операции, в которой задействована sag-а:
- 0 (неизвестное)
- 1 (регистрация ЮР лица)
- 2 (создание счёта для ЮР лица)
- 255 (ошибка)
При получении удачно выполненного event-а убираем его из списка. В случае, когда все event-ы выполнились, то меняем состояние саги с 20 на 30. В случае, если пришёл неудачный event, то меняем статус саги на с 20 на 255.
Поле saga_data хранит все данные, необходимые для его event-ов, а также данные, которые могут быть получены в результате выполнения event-а. Формат json поля следующий
{
"name_1": ...,
...
"name_n": ...
}
operation_uuid- уникальный id операции, в рамках которой выполняется SAGA
Таблица зависимостей sag
| current_saga_uuid | next_saga_uuid | acc_connection_status |
|---|---|---|
| uuid | uuid | numeric(3) |
Значения поля status:
0- неизвестный10- ожидает выполнения текущей саги20- выполнена удачно30- откат255- ошибка
Данная таблица отвечает за то, что отвечает за последовательность саг в запросе. Т.е. следующая сага не может быть запущена, пока в данное таблице не будет записей с uuid саги next_saga_uuid.
Таблица событий
| event_uuid | saga_uuid | event_status | event_name | event_is_roll_back | event_required_data | event_result | event_rollback_uuid |
|---|---|---|---|---|---|---|---|
| uuid | uuid | numeric(3) | varchar(64) | bool | json | json | uuid |
Содержит события саг. Статус имеет следующие значения:
0(undefined)10(created)20(in progress)30(completed)40(fallback in process)50(fallback completed)250(fallback error)255(error)
В event_required_data лежит список необходимых полей для данного event-а. Формат следующий:
{
[
"name_1",
...
"name_n"
]
}
Данные берутся из поля saga_data из данных sag-и.
В event_result лежит результат, полученный в ответ от другого сервиса.
event_rollback_uuid - поле, в котором лежит uuid того event-а, которое откатывает текущее.
Список запросов, необходимых для репозитория:
- создание sag-и
- удаление sag-и
- обновление sag-и
- создание event-a
- удаление event-а
- обновление event-а
- создание связи между sag-ми
- удаление связи между Sag-ми
- обновление статуса связи между sag-ми
- получение списка uuid всех event-ов sag-и
- получение списка связей текущей Sag-и, где текущая sag-а зависит от других
- получение списка связей текущей sag-и, где от текущей Sag-и зависят другие
Механизм sag
Список названий event-ов
- Сервис счетов
- Reserve account
- Create acccount
- Open account
- closse account
- get_account_data
- Сервис пользователей
- Create user
- Add account to user
- get_user_data
- check_user_password
- update_user_password
- get_user_data_by_login
Список выполняемых операция и sag в них с event-ми
- Create user (простая)
Зависимость sag: create_userSaga №1: create_userEvent-ы: Create user
- Add account to user (составная)
Зависимость sag: check_user -> reserve_acc -> create_acc -> open_acc_and_add_to_userSaga №1: check_userEvent-ы: check_user
Saga №2: reserve_accEvent-ы: Reserve acc
Saga №3: create_accEvent-ы: Create acc
Saga №4: open_acc_and_add_to_userEvent-ы: Open acc + Add account to user
- Add accoun cache (составная)
Зависимость sag: check_user->get_account_data->add_account_cacheSaga №1: check_userEvent-ы: get_user_data
Saga №2: get_account_dataEvent-ы: get_account_data
Saga №3: add_account_cacheEvent-ы: add_account_cache
- Width accoun cache (составная)
Зависимость sag: check_user->get_account_data->width_account_cacheSaga №1: check_userEvent-ы: get_user_data
Saga №2: get_account_dataEvent-ы: get_account_data
Saga №3: width_account_cacheEvent-ы: width_account_cache
- Close account (составная)
Зависимость sag: check_user->get_account_data->close_accountSaga №1: check_userEvent-ы: get_user_data
Saga №2: get_account_dataEvent-ы: get_account_data
Saga №3: close_accountEvent-ы: close_account
- Get user data (простая)
Зависимости sag: check_userSaga №1: check_userEvent-ы: get_user_data
- Get account data (составная)
Зависимость sag: check_user->get_account_dataSaga №1: check_userEvent-ы: get_user_data
Saga №2: get_account_dataEvent-ы: get_account_data
- Update_user_password
Зависимость sag: update_user_passwordSaga №1: update_user_passwordEvent-ы: update_user_password
- Get_user_data_by_login
Зависимость sag: get_user_data_by_loginSaga №1: get_user_data_by_loginEvent-ы: get_user_data_by_login
- Check_user_password
Зависимость sag: check_user_passwordSaga №1: check_user_passwordEvent-ы: check_user_password
Формирование sag дерева sag операции
Структура одноименных с операцией Sag внутри сервиса будет представляться в виде уровней дерева:
1)Выбрать следующую sag-у текущего уровня дерева.
2)Создать выбранную пустую sag-у со статусом 0.
3)Добавить uuid созданной sag-и в map с номером sag-и в дереве.
4)У текущей sag-и есть зависимость от других sag? Если да, то идем в пункт 5, иначе, идём в пункт 8.
5)Выбрать следующую sag-у, от которой зависит текущая.
6)Связать текущую sag-у с зависимой по номеру sag-и в map-е.
7)Зависимая sag-а была последней? Если нет, то идём в пункт 5, иначе идём в пункт 8.
8)Создать события со статусом созданных (10), которые должны быть в sag-e.
9)Sag-а является последней в уровне дерева? Если нет, то идём в пункт 1, иначе идём в пункт 10.
10)Уровень дерева является последним? Если нет, то идём в пункт 11, иначе в пункт 12.
11)Переходим на следующий уровень дерева. Идём в пункт 1.
12)Проходимся по map-е и изменяем статус sag на созданный (10)
Работа механизма sag
Обработка событий и sag происходят в go-рутинах. Так что алгоритм рассчитан на много поточное выполнение.
1)Текущая Sag-а зависит от других саг? Если да, то идём в 2, иначе идём в 5.
2)Все sag-и, от которых зависим выполнились? Если да, то идём в 5, иначе идём в 3.
3)Ожидание. Идём в пункт 2.
4)Изменяем статус текущей sag-и на исполняемую (20).
5)Проход по всем событиям sag-и, изменение их статуса на исполняемую (20) и отправка соответствующих им запросов на соответствующие сервисы.
6)Ожидание получения ответов на event-ы.
7)Полученный ответ на event удачный? Если да, то идём в пункт 8, иначе идём в 17.
8)Изменяем статус event-а на выполненный (30). Добавление новых данных в sag-у, к которой относится event.
9)Event откатывает другой (флаг event_is_roll_back)? Если да, то идём в пункт 27, иначе идём в пункт 10.
10)На все event-ы sag-и получен ответ? Если да, то идём в пункт 11, иначе идём в пункт 6.
11)Все события sag-и выполнились удачно, т.е. имеют статус выполненной (30)? Если да, то идём в пункт 12, иначе идём в пункт 28.
12)Изменение статуса sag-и на выполненное удачно (30).
13)От текущей sag-и зависят другие sag-и? Если да, то идём в пункт 14, иначе идём в пункт 15.
14)Изменение статуса связи между текущей sag-ой и зависящих на выполненную удачно (20). Прокидывание в зависимые sag-и данные из текущей sag-и.
15)Все sag-и выполнились? Если да, то идём в пункт конец, иначе идём в пункт 16.
16)Переключаемся на следующую невыполненную sag-у (речь идёт про многопточность). Идём в пункт 1.
17)Изменение статуса event-а на ошибку (255).
18)Event откатывает другой (флаг event_is_roll_back)? Если да, то идём в пункт 19, иначе идём в пункт 20.
19)У откатываемого event-а меняем статус на ошибка в откатывании (250).
20)Sag-а уже откатывается? Если да, то идём в пункт 22, иначе идём в пункт 21.
21)Изменение статуса sag-и на откат (40).
22)В sag-е есть удачно выполненные (30) event-ы, не являющихся обратными (флаг event_is_roll_back)? Если да, то идём в пункт 23, иначе идём в пункт 10.
23)Выбрать следующий удачно выполненный (30) event, поменять статус на откатываемый (40).
24)Создать откатывающий event к текущему в статусе созданного (10) и с поднятым флагом откатывания другого (event_is_roll_back).
25)Привязать созданный event к откатываемому.
26)Изменить статус созданного event-а на в процессе (20) и отправка соответствующего запроса на соответствующий сервис. Идём в пункт 22.
27)Изменение статуса откатываемого event-а текущим на удачный откат (50). Идём в пункт 10.
28)Текущая сага имеет ошибки в событиях (255)? Если да, то идём в пункт 29, иначе идём в пункт 30.
29)Изменение статуса sag-и на ошибочную (255).
30)Текущая сага имеет ошибки откатывания в событиях (250)? Если да, то идём в пункт 31, иначе идём в пункт 32.
31)Изменение статуса sag-и на ошибочную в откатах (250).
32)Текущая sag-а зависит от других sag? Если да, то идём в пункт 33, иначе идём в пункт 35.
33)Изменение статуса связи между текущей sag-ой и теми, от которых зависит текущая на откат (30).
34)Переход во все sag-и, от которых зависит текущая sag-а.
35)Есть sag-и, которые завися от текущей и связь между текущей и зависимой в статусе выполнено удачно (20)? Если да, то идём в пункт 36, иначе в пункт 21.
36)Переход во все sag-и, которые зависят от текущей со статусом связи выполнено удачно (20). Идём в пункт 35.
конец)Завершилась обработка всех sag операции
Пример
Уровень бизнес логики
Уровень sag
- создать sag-у
- откатить sag-у
- удалить sag-у
- создать event
- откатить event
- удалить event
- отправить запрос, реализующий event
- обработать ответ на event
Уровень операция бизнеса
- создать пользователя
- открыть счёт для пользователя (будет реализовываться после первой операции)
Уровень REST API
Операции
- Регистрация пользователя
- Регистрация счёта пользователя
- Закрытие счёта
- Снятие со счёта
- Пополнение счёта
- получить данные пользователя
- получить данные счёта
- обновить пароль пользователя
- получить данные пользователя по логину
- проверить пароль пользователя
- Узнать состояние операции
- Получить данные об операции, для построения дерева
- Получить список операций за указанный промежуток времени
Регистрация пользователя
Информация о запросе
- тип запроса - POST
-
url - http://localhost:8080/api/v1/registration/create_user
Входные данные запроса
{
"user_inn": "01234567890123456789",
"passport": {
"series": "0123",
"number": "012345",
"name": "...",
"surname": "...",
"patronymic": "...",
"birth_date": "01-01-2001 01:01:01",
"birth_location": "...",
"pick_up_point": "...",
"authority": "012-345",
"authority_date": "01-01-2001 01:01:01",
"registration_address": "...",
},
"user_data": {
"login": "...",
"password": "..."
}
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ начала операции -
202 - ошибка в данных пользователя -
400 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 202,
"info": "operation_id(uuid)",
"additional_info": { # не является обязательным
"...": "...",
...
"...": ...
},
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Регистрация счёта пользователя
Информация о запросе
- тип запроса - POST
-
url - http://localhost:8080/api/v1/registration/open_account
Входные данные запроса
{
"user_id": "uuid",
"acc_name": "...",
"culc_number": "...",
"corr_number": "...",
"bic": "...",
"cio": "...",
"reserve_reason": "..."
}
Возможные ответы на запрос и их статусы
Статусы
- Счёт создан -
201 - ошибка в данных пользователя -
400 - пользователь на найден -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 201,
"info": "account_id(uuid)"
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Закрытие счёта
Информация о запросе
{
"user_id": "uuid",
"account_id": "uuid"
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
202 - ошибка в данных пользователя -
400 - нет указанного пользователя или счёта -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 202,
"info": "operation uuid"
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Пополнение счёта
Информация о запросе
- тип запроса - POST
-
url - http://localhost:8080/api/v1/registration/add_account_cache
Входные данные запроса
{
"user_id": "uuid",
"account_id": "uuid",
"cache_diff": 1234567 # Может быть как целым, так и дробным.
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
202 - ошибка в данных пользователя -
400 - нет указанного пользователя или счёта -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 202,
"info": "operation uuid"
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Снятие со счёта
Информация о запросе
- тип запроса - POST
-
url - http://localhost:8080/api/v1/registration/width_account_cache
Входные данные запроса
{
"user_id": "uuid",
"account_id": "uuid",
"cache_diff": 1234567 # Может быть как целым, так и дробным.
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
202 - ошибка в данных пользователя -
400 - нет указанного пользователя или счёта -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 202,
"info": "operation uuid"
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Получение данных пользователя
Информация о запросе
- тип запроса - POST
-
url - http://localhost:8080/api/v1/registration/get_user_data
Входные данные запроса
{
"user_id": "uuid"
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
202 - ошибка в данных пользователя -
400 - нет указанного пользователя или счёта -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 202,
"info": "operation uuid"
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Получение данных счёта
Информация о запросе
- тип запроса - POST
-
url - http://localhost:8080/api/v1/registration/get_account_data
Входные данные запроса
{
"user_id": "uuid",
"account_id": "uuid"
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
202 - ошибка в данных пользователя -
400 - нет указанного пользователя или счёта -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 202,
"info": "operation uuid"
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Обновить пароль пользователя
Информация о запросе
- тип запроса - POST
-
url - http://localhost:8080/api/v1/registration/update_password
Входные данные запроса
{
"user_id": "uuid",
"new_password": "..."
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
202 - ошибка в данных пользователя -
400 - нет указанного пользователя -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 202,
"info": "operation uuid"
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Получить данные пользователя по логину
Информация о запросе
- тип запроса - POST
-
url - http://localhost:8080/api/v1/registration/user_data_by_login
Входные данные запроса
{
"user_login": "..."
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
202 - ошибка в данных пользователя -
400 - нет указанного пользователя -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 202,
"info": "operation uuid"
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Проверить пароль пользователя
Информация о запросе
- тип запроса - POST
-
url - http://localhost:8080/api/v1/registration/check_password
Входные данные запроса
{
"user_id": "uuid",
"password": "..."
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
202 - ошибка в данных пользователя -
400 - нет указанного пользователя -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 202,
"info": "operation uuid"
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Узнать состояние операции
Информация о запросе
- тип запроса - GET
-
url - http://localhost:8080/api/v1/registration/get_operation_status
Входные данные запроса
{
"operation_id": "uuid",
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ -
200 - ошибка в данных пользователя -
400 - операция не найдена -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 200,
"info": "in process",
"additional_info": { # может и отсутствовать
...
}
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Получить данные об операции, для построения дерева
Информация о запросе
- тип запроса - GET
-
url - http://localhost:8080/api/v1/registration/get_operation_tree_data
Входные данные запроса
{
"operation_id": "uuid"
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
200 - ошибка в данных пользователя -
400 - нет указанного пользователя -
404 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 200,
"info": {
"operation_name": "...",
"saga": [
{
"id": "...",
"status": 999,
"name": "...",
"events": [
"event_id",
...
"event_id_n"
]
},
...
{
...
}
],
"events": [
{
"id": "...",
"name": "...",
"status": 999,
"roll_back_id": "..."
},
...
{
...
}
],
"saga_depend": [
{
"parent_id": "...",
"child_id": "..."
}
]
}
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
Получить список операций за указанный промежуток времени
Информация о запросе
- тип запроса - GET
-
url - http://localhost:8080/api/v1/registration/get_operations_range
Входные данные запроса
{
"time_begin": "time",
"time_end": "time_end"
}
Возможные ответы на запрос и их статусы
Статусы
- удачный ответ (операция выполняется) -
200 - ошибка в данных пользователя -
400 - внутренняя ошибка сервера -
500
Ответы
- Удачный:
{
"status": 200,
"info": {
"operations": [
"operation_id",
...
"operation_id_n"
]
}
}
- Ошибочный:
{
"status": 400,
"info": "Input data validation error"
}
- Страницы
- README
- Service-Accounts
- Service-ApiGateway
- Service-Notification
- Service-Registration
- Service-TOTP
- Service-Users