It's a toy project, test item #1 for Embedika company, simple microservice used to provide downloaded and parsed oil prices, nothing to see here.
Это микросервис на akka-http, предоставляющий несколько эндпойнтов для получения информации о ценах на нефть.
Для своей внутренней логики сервис кэширует и пытается раз в час обновлять записи с ценами с Data.gov.ru,
но он больше времени лежит, чем стоит, поэтому есть фоллбэк на локальный файл с ценами в JAR’е. HTTP-запросы кэшируются отдельно через akka-http-caching
.
Записи с ценами в памяти поддерживаются отсортированными по возврастанию даты для возможности бинарного поиска ближайшей к целевой дате записи.
Чтобы не потерять точность и избежать ошибок округления при работе с ценами, используется Squants.
Статистики нет, хотя планировалась, но увы. Фронта нет и не планировалось.
OilPriceSource
предоставляет локальное и удалённое места, откуда можно получить сырые данные с ценами;OilPriceProvider
абстрагирует то, как сырые данные получаются и превращаются в распарсенные цены, аOilPriceCsvParser
ему помогает в парсинге CSV.OilPriceCache
скрывает процесс получения свежих цен от провайдеров и обновления их в памяти, позволяя просто делать get() и не думать о том, пойдём мы в интернет или не пойдём.OilPriceService
реализует бизнес-логику эндпойнтов: расчёты средней-минимальной-максимальной цен нахоядтся в нём.OilPriceServiceRoutes
содержит сами эндпойнты с валидацией параметров.- Его помощник
Routes
оборачивает эндпойнты в общую для всех обвязку. - Контексты выполнения явно разделяются на
CpuExecutionContext
иIoExecutionContext
, чтобы не запутаться в implicit’ах и не перепутать, на чём качать цены, а на чём находить минимум-максимум. - Архитектура заточена под нескольких провайдеров, но реально существует только один: data.gov.ru
Формат даты во всех эндпойнтах — стандартный ISO-8601: 2013-04-14
curl --request GET \
--url http://127.0.0.1:8045/prices/data.gov.ru/all
Пример возвращаемого JSON-списка:
[
{
"dates": "2013-03-15, 2013-04-14",
"price": "764.6 RUB"
},
{
"dates": "2013-04-15, 2013-05-14",
"price": "732.8 RUB"
},
{
"dates": "2013-05-15, 2013-06-14",
"price": "749.3 RUB"
}
]
curl --request GET \
--url 'http://127.0.0.1:8045/prices/data.gov.ru/single?date=2020-12-31'
Пример возвращаемой JSON-строки: "377.4 RUB"
Возвращает 404, если у провайдера нет записей о цене на заданную дату.
curl --request GET \
--url 'http://127.0.0.1:8045/prices/data.gov.ru/averageover?startDate=2019-12-31&endDate=2021-01-01'
Пример возвращаемой JSON-строки: "303.7 RUB"
Возвращает 404, если заданный диапазон дат не пересекается ни с одной записью о цене.
curl --request GET \
--url 'http://127.0.0.1:8045/prices/data.gov.ru/minmax?startDate=2019-01-01&endDate=2021-01-01'
Пример возвращаемого JSON-объекта:
{
"min": "138.7 RUB",
"max": "527.3 RUB"
}
Возвращает 404, если заданный диапазон дат не пересекается ни с одной записью о цене.
curl --request GET \
--url http://127.0.0.1:8045/prices/stats
Пример возвращаемого JSON-массива:
[
{
"providerId": "Data.gov.ru",
"totalOilPriceRecords": 111
}
]
sbt run
, или если хочется вызвать отдельный исполняемый файл,
можно сделать sbt pack
и вызвать .\target\pack\bin\main
.
Если же нужен архив с программой: sbt Universal / packageBin
.
Образ делается через sbt-native-packager,
настраиваемый в build.sbt
.
Создать локальный образ и запустить его можно так (сервис слушает 8045 порт и выключается по ньюлайну в stdin):
sbt Docker / publishLocal
docker run -i -p 8045:8045 oil-price-service:1.0.0
Задание рассчитано на выполнение в течении не более 16 часов рабочего времени. Желательно выполнить на Scala но можно и на одном из языков (C#, Java, …).
Внимание! Тестовые задания на Python, в одном файле, в процедурном стиле - не принимаются т.к. задания выполненные в подобном стиле не могут показать нам ваши навыки построения приложения.
Исходный код необходимо предоставить в виде репозитория на github или аналогичном сервисе. Также необходимо написать небольшой документ с описанием архитектуры приложения. По умолчанию предполагается API - REST.
Необходимо распарсить открытые данные о цене на сырую нефть марки «Юралс» и предоставить к ним доступ по API.
Метод | Параметры | Возвращаемый результат |
---|---|---|
Цена на заданную дату | Дата | Значение цены |
Средняя цена за промежуток времени | Диапазон дат | Значение цены |
Максимальная и минимальная цены за промежуток времени | Диапазон дат | Json с полями min и max |
Статистика по загруженным данным | Нет параметров | Json с полями всего записей |
- Сохранение запросов к сервису и вывод лога в api;
- Статистика запросов к сервису (сколько, время обработки и прочее);
- Кэширование запросов;
- Docker файл для развертывания сервиса;
- Фронтенд для сервиса;
- Unit тесты;
- GraphQL для API.