/chartographer

Test project for Kontur internship summer 2022

Primary LanguageC++MIT LicenseMIT

Chartographer

От charta (лат.) или харта — одно из названий папируса.

Необходимо написать сервис Chartographer — сервис для восстановления изображений древних свитков и папирусов. Изображения растровые и создаются поэтапно, отдельными фрагментами. Восстановленное изображение можно получать фрагментами, даже если оно лишь частично восстановленное.

HTTP API

Методы

POST /chartas/?width={width}&height={height}

Создать новое изображение папируса заданного размера (в пикселях), где {width} и {height} — положительные целые числа, не превосходящие 20 000 и 50 000, соответственно. Тело запроса пустое. В теле ответа возвращается {id} — идентификатор изображения, например: 876b8335-3279-4f59-9718-570f37f076ea. Код ответа: 201 Created.

POST /chartas/{id}/?x={x}&y={y}&width={width}&height={height}

Сохранить восстановленный фрагмент изображения размера {width} x {height} с координатами ({x}; {y}). Под координатами подразумевается положение левого верхнего угла фрагмента относительно левого верхнего угла всего изображения. Другими словами, левый верхний угол изображения является началом координат, т.е. эта точка имеет координаты (0; 0). Тело запроса: изображение в формате BMP (цвет в RGB, 24 бита на 1 пиксель, без сжатия). Тело ответа пустое. Код ответа: 200 OK.

GET /chartas/{id}/?x={x}&y={y}&width={width}&height={height}

Получить восстановленную часть изображения размера {width} x {height} с координатами ({x}; {y}). Под координатами подразумевается положение левого верхнего угла фрагмента относительно левого верхнего угла всего изображения. Другими словами, левый верхний угол изображения является началом координат, т.е. эта точка имеет координаты (0; 0). Тело ответа: изображение в формате BMP (цвет в RGB, 24 бита на 1 пиксель, без сжатия). Код ответа: 200 OK.

DELETE /chartas/{id}/

Удалить изображение с идентификатором {id}. Тело запроса и ответа пустое. Код ответа: 200 OK.

Обработка ошибок

  1. Запросы по {id} изображения, которого не существует, должны завершаться с кодом ответа 404 Not Found.
  2. Запросы с некорректными параметрами {width} или {height} должны завершаться с кодом ответа 400 Bad Request.
  3. Запросы с фрагментами, которые не пересекаются по координатам с изображением, должны завершаться с кодом ответа 400 Bad Request. При этом фрагменты могут частично находиться вне границ изображения (см. примечания) — такие запросы считаются корректными.

Примечания

  1. Размер изображений не превосходит 20 000 x 50 000.
  2. Некоторые изображения гарантировано не смогут поместиться целиком в памяти. Необходимо предусмотреть возможность хранения данных на диске.
  3. Формат изображения — Microsoft/Windows BMP, RGB, 8 бит на компоненту без сжатия.
  4. В случае, если загружаемый восстановленный фрагмент перекрывает восстановленную ранее часть, то в любом случае применяется новый фрагмент.
  5. Если запрашивается фрагмент, часть которого ещё не восстановлена, то не восстановленные области закрашиваются чёрным цветом. Аналогично, чёрным цветом закрашивается та часть фрагмента, которая оказывается вне границ изображения (см. пример ниже).
  6. Если восстанавливаемый фрагмент перекрывает границы изображения, то часть фрагмента вне изображения игнорируется. Пример: размер изображения — 50 x 100, фрагмент с размером 50 x 50 и координатами верхнего левого угла (25;25). Правая половина фрагмента игнорируется. Схематически изображено ниже.
╔═════════╗
║         ║
║    ┌────╫────┐
║    │    ║    │
║    │    ║    │
║    │    ║    │
║    └────╫────┘
║         ║
╚═════════╝

Ожидается, что решение будет в первую очередь корректно работать и успешно обрабатывать ошибки. В качестве усложнения задачи предлагается:

  1. Гарантировать корректную работу с изображениями, которые не смогут поместиться целиком в оперативной памяти. Необходимо предусмотреть возможность хранения данных на диске.
  2. Гарантировать стабильную работу сервиса в нагруженной среде на многоядерной машине.

Лучше предоставить более простую, но корректно работающую реализацию, чем пытаться сделать самый сложный вариант, но в итоге не отправить решение.

Настоятельно рекомендуется покрыть основную функциональность unit-тестами.

Начальный проект

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

  • cmake
  • conan
  • компилятор с поддержкой C++17

Собрать проект можно через консоль:

cmake -S . -B /path/to/build/dir
cmake --build /path/to/build/dir --config Release

где /path/to/build/dir — директория, содержащая сконфигурированный проект и артефакты сборки. Бинарный файлы после сборки сохраняются в поддиректории build/bin/<config>/.

Для удобства разработки проект был разделён на три компоненты:

  • core — статическая библиотека, хранящая основную логику программы.
  • server — веб-сервер.
  • tests — модульные тесты.

С этой структурой легко автоматизировать проверку корректности программы или её отдельных частей — достаточно выделить проверяемую логику в компоненту core и написать на неё тесты в tests. ;)

В проект включены следующие библиотеки:

Т.к. POCO — крупный фреймворк, поэтому ниже приведены ссылки на ознакомление с модулями, необходимыми для выполнения задания:

Требования к оформлению решения

  • Компиляция кода и его исполнение c использованием C++17.
  • Код должен быть кросс-платформенным, т.е. нельзя использовать компиляторо-зависимые расширения языка и стандартной библиотеки.
  • Использование только тех библиотек, что добавлены в начальный проект.
  • Сборка сервиса при помощи cmake.
  • Запуск сервиса осуществляется командой server -f /path/to/content/folder, где /path/to/content/folder – путь до каталога, в котором сервис может хранить данные.
  • В архиве должны находиться только исходные коды.
  • Сервис должен принимать HTTP-запросы на стандартном порту (8080).

В качестве исключения допустимо использовать иные библиотеки, но в таком случае проект должен собираться на ОС Windows с Visual Studio 2019 (16.11.9) и на ОС Linux с GCC 10 без дополнительной настройки окружения.

Информация по тестированию

Сервис будет запускаться в Docker. Контейнеру будет предоставлено не менее 2 Гбайт оперативной памяти и не менее 20 Гбайт места на диске.

Возможные проблемы

После добавления исходных файлов, они не появляются в проекте / не участвуют в сборке.

После создания исходных файлов нужно переконфигурировать проект. Для этого нужно ввести команду cmake /path/to/build/dir. Если рабочая директория является директорией проекта, то достаточно — cmake .

Конфигурация CMake завершается ошибкой HTTPSConnectionPool(host='conan.bintray.com', port=443): Max retries exceeded with url: /v1/ping

conan.bintray.com — устаревший репозиторий пакетов Conan. Добавьте новый репозиторий командой:

conan remote add -i 0 conancenter https://center.conan.io