Сервис "Календарь" представляет собой максимально упрощенный сервис для хранения календарных событий и оправки уведомлений.
Сервис предполагает возможность:
- добавить/обновить событие;
- получить список событий на день/неделю/месяц;
- получить уведомление за N дней до события.
Сервис НЕ предполагает:
- авторизации;
- разграничения доступа;
- web-интерфейса.
Полностью завершенный сервис состоит из 5 процессов.
API предоставляет собой GRPC и HTTP интерфейсы для пользователей. API реализуют основные методы сервиса. Так как авторизация и разделение доступа выходят за рамки сервиса, мы предполагаем, что ID пользователя просто передается через параметры / метаданные / заголовок запроса.
Планировщик - это фоновый процесс, который не взаимодействует с пользователем и выполняет периодические задания:
- выбор событий, требующих уведомления и отправка уведомлений в очередь рассыльщику;
- очистка старых (более 1 года назад) событий.
Рассыльщик - это фоновый процесс, занимающийся отправкой уведомлений.
В рамках задания нет необходимости реальной отправки сообщений, достаточно, если рассыльщик просто будет записывать их в лог / выводить в STDOUT.
Реляционная СУБД (например, PostgreSQL) - хранит информацию о событиях.
Очередь сообщений (RabbitMQ) - используется для передачи уведомлений от Планировщика Рассыльщику.
Событие - основная сущность, содержит в себе поля:
- ID - уникальный идентификатор события (можно воспользоваться UUID);
- Заголовок - короткий текст;
- Дата и время события;
- Длительность события (или дата и время окончания);
- Описание события - длинный текст, опционально;
- ID пользователя, владельца события;
- За сколько времени высылать уведомление, опционально.
Уведомление - временная сущность, в БД не хранится, складывается в очередь для рассыльщика, содержит поля:
- ID события;
- Заголовок события;
- Дата события;
- Пользователь, которому отправлять.
- Создать (событие);
- Обновить (ID события, событие);
- Удалить (ID события);
- СписокСобытийНаДень (дата);
- СписокСобытийНаНеделю (дата начала недели);
- СписокСобытийНaМесяц (дата начала месяца).
Рекомендуется собирать проект в виде трех бинарных файлов, по одному на каждый микросервис. Каждый из сервисов должен принимать путь файлу конфигурации:
./calendar --config=/path/to/calendar_config.yaml
./calendar_scheduler --config=/path/to/scheduler_config.yaml
./calendar_sender --config=/path/to/sender_config.yaml
Проект следует оформить в виде набора контейнеров для каждого из микросервисов. Поскольку запуск будет осуществлять в контейнерах - логи нужно печатать в STDERR. Сервисы должны получать настройки (например, адрес и логин в СУБД) через переменные окружения. При желании можно использовать конфиг viper, с поддержкой переменных окружения.
Развертывание микросервиса должно осуществляться командой docker-compose up
в директории с проектом.
Для проекта необходимо реализовать интеграционные тесты, т.е. тесты проверяющие работу на уровне API.
Интеграционные тесты можно создать с помощью BDD, а можно просто с помощью стандартного пакета testing
и запускать их в отдельном контейнере в том же compose окружении, что и остальные микросервисы.
В таком случае тесты смогут получать адрес работающего сервиса через переменные окружения, выполнять запросы к нему,
а также проверять состояние базы данных и пр.
Разработка разделена на следующие этапы (ДЗ):
- Разрабатываем скелет сервиса: конфигурирование, работа с базой, простой web-сервер.
- Добавляем HTTP и GRPC API.
- Выдялем Планировщик и Рассыльщик. Интегрируемся с очередью сообщений.
- Создаем Docker-образы, docker-compose конфигурации, пишем интеграционные тесты.
Таким образом, на каждом этапе мы получаем осмысленный проект.