AUTH SERVER
- set CMAke project - add Drogon submodule - add json and Catch2 submodule - add health check endpoint -RAII SqliteDb - Verify DB and HTTP some work
This commit is contained in:
@@ -0,0 +1,56 @@
|
|||||||
|
BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: '-2'
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: 'true'
|
||||||
|
AlignConsecutiveDeclarations: 'true'
|
||||||
|
AlignEscapedNewlines: Left
|
||||||
|
AlignOperands: 'true'
|
||||||
|
AlignTrailingComments: 'true'
|
||||||
|
AllowAllConstructorInitializersOnNextLine: 'false'
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: 'true'
|
||||||
|
AllowShortBlocksOnASingleLine: 'false'
|
||||||
|
AllowShortCaseLabelsOnASingleLine: 'true'
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLambdasOnASingleLine: Inline
|
||||||
|
AllowShortLoopsOnASingleLine: 'false'
|
||||||
|
AllowShortCompoundRequirementOnASingleLine: 'true'
|
||||||
|
AlwaysBreakTemplateDeclarations: 'Yes'
|
||||||
|
BinPackArguments: 'true'
|
||||||
|
BinPackParameters: 'true'
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeTernaryOperators: 'true'
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakInheritanceList: BeforeComma
|
||||||
|
BreakBeforeConceptDeclarations: Always
|
||||||
|
ColumnLimit: '100'
|
||||||
|
CompactNamespaces: 'false'
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: 'false'
|
||||||
|
Cpp11BracedListStyle: 'false'
|
||||||
|
FixNamespaceComments: 'true'
|
||||||
|
IncludeBlocks: Regroup
|
||||||
|
IndentCaseLabels: 'true'
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
IndentWidth: '2'
|
||||||
|
IndentWrappedFunctionNames: 'false'
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: 'false'
|
||||||
|
Language: Cpp
|
||||||
|
MaxEmptyLinesToKeep: '1'
|
||||||
|
RequiresExpressionIndentation: OuterScope
|
||||||
|
SortIncludes: 'true'
|
||||||
|
SortUsingDeclarations: 'true'
|
||||||
|
SpaceAfterCStyleCast: 'false'
|
||||||
|
SpaceAfterLogicalNot: 'false'
|
||||||
|
SpaceAfterTemplateKeyword: 'true'
|
||||||
|
SpaceBeforeAssignmentOperators: 'true'
|
||||||
|
SpaceBeforeCpp11BracedList: 'false'
|
||||||
|
SpaceBeforeCtorInitializerColon: 'false'
|
||||||
|
SpaceBeforeInheritanceColon: 'false'
|
||||||
|
SpaceBeforeParens: Never
|
||||||
|
SpaceInEmptyParentheses: 'false'
|
||||||
|
SpacesInAngles: 'false'
|
||||||
|
SpacesInContainerLiterals: 'false'
|
||||||
|
SpacesInParentheses: 'false'
|
||||||
|
Standard: Cpp11
|
||||||
|
TabWidth: '2'
|
||||||
|
UseTab: Never
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[submodule "submodules/drogon"]
|
||||||
|
path = submodules/drogon
|
||||||
|
url = https://github.com/drogonframework/drogon.git
|
||||||
|
[submodule "submodules/json"]
|
||||||
|
path = submodules/json
|
||||||
|
url = https://github.com/nlohmann/json.git
|
||||||
|
[submodule "submodules/Catch2"]
|
||||||
|
path = submodules/Catch2
|
||||||
|
url = https://github.com/catchorg/Catch2.git
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Run auth_service",
|
||||||
|
"type": "cppdbg",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceFolder}/build/auth_service",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceFolder}",
|
||||||
|
"stopAtEntry": false,
|
||||||
|
"MIMode": "gdb",
|
||||||
|
"miDebuggerPath": "/usr/bin/gdb",
|
||||||
|
"preLaunchTask": "build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Vendored
+43
@@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"version": "2.0.0",
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"label": "build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "cmake",
|
||||||
|
"args": [
|
||||||
|
"--build",
|
||||||
|
"build",
|
||||||
|
"--target",
|
||||||
|
"auth_service"
|
||||||
|
],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "run",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "./build/auth_service",
|
||||||
|
"dependsOn": "build",
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "test",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "ctest",
|
||||||
|
"args": [
|
||||||
|
"--test-dir",
|
||||||
|
"build",
|
||||||
|
"--output-on-failure"
|
||||||
|
],
|
||||||
|
"dependsOn": "build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.22)
|
||||||
|
|
||||||
|
project(auth_service VERSION 0.1.0 LANGUAGES CXX)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 20)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
include(CTest)
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
find_package(SQLite3 REQUIRED)
|
||||||
|
|
||||||
|
add_subdirectory(submodules/drogon)
|
||||||
|
add_subdirectory(submodules/json)
|
||||||
|
add_subdirectory(submodules/Catch2)
|
||||||
|
|
||||||
|
add_executable(auth_service
|
||||||
|
src/main.cpp
|
||||||
|
src/application/application.cpp
|
||||||
|
src/http/controllers/health_controller.cpp
|
||||||
|
src/db/sqllite_db.cpp
|
||||||
|
src/db/statement.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(auth_service
|
||||||
|
PRIVATE
|
||||||
|
${PROJECT_SOURCE_DIR}/include
|
||||||
|
${PROJECT_SOURCE_DIR}/src
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(auth_service PRIVATE
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-Wpedantic
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(auth_service PRIVATE
|
||||||
|
drogon
|
||||||
|
SQLite::SQLite3
|
||||||
|
nlohmann_json::nlohmann_json
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(auth_service_tests
|
||||||
|
tests/smoke_test.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(auth_service_tests
|
||||||
|
PRIVATE
|
||||||
|
${PROJECT_SOURCE_DIR}/include
|
||||||
|
${PROJECT_SOURCE_DIR}/src
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(auth_service_tests PRIVATE
|
||||||
|
-Wall
|
||||||
|
-Wextra
|
||||||
|
-Wpedantic
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(auth_service_tests PRIVATE
|
||||||
|
Catch2::Catch2WithMain
|
||||||
|
nlohmann_json::nlohmann_json
|
||||||
|
)
|
||||||
|
|
||||||
|
include(${PROJECT_SOURCE_DIR}/submodules/Catch2/extras/Catch.cmake)
|
||||||
|
catch_discover_tests(auth_service_tests)
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
#include "application/application.hpp"
|
||||||
|
// #include <nlohmann/json.hpp>
|
||||||
|
#include "db/sqllite_db.hpp"
|
||||||
|
#include "http/controllers/health_controller.hpp"
|
||||||
|
|
||||||
|
#include <drogon/drogon.h>
|
||||||
|
#include <format>
|
||||||
|
#include <iostream>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
namespace {
|
||||||
|
void register_routes() {
|
||||||
|
static HealthController health_controller;
|
||||||
|
drogon::app().registerHandler(
|
||||||
|
"/health",
|
||||||
|
[](const drogon::HttpRequestPtr &req,
|
||||||
|
std::function<void(const drogon::HttpResponsePtr &)> &&callback) {
|
||||||
|
health_controller.handle(req, std::move(callback));
|
||||||
|
},
|
||||||
|
{ drogon::Get });
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Application::Application(Settings settings)
|
||||||
|
: settings_(std::move(settings)) {}
|
||||||
|
|
||||||
|
int Application::run() const {
|
||||||
|
SqlliteDb db(settings_.db_path);
|
||||||
|
db.initialize();
|
||||||
|
|
||||||
|
// {
|
||||||
|
// db.execute("CREATE TABLE IF NOT EXISTS healthcheck_tmp ("
|
||||||
|
// "id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
||||||
|
// "name TEXT NOT NULL"
|
||||||
|
// ");");
|
||||||
|
|
||||||
|
// {
|
||||||
|
// auto insert_stmt = db.prepare("INSERT INTO healthcheck_tmp(name) VALUES(?1);");
|
||||||
|
// insert_stmt.bind_text(1, "boot");
|
||||||
|
// insert_stmt.execute();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// {
|
||||||
|
// auto select_stmt =
|
||||||
|
// db.prepare("SELECT id, name FROM healthcheck_tmp ORDER BY id DESC LIMIT 1;");
|
||||||
|
|
||||||
|
// if(select_stmt.step()) {
|
||||||
|
// const auto id = select_stmt.column_int64(0);
|
||||||
|
// const auto name = select_stmt.column_text(1);
|
||||||
|
|
||||||
|
// std::cout << "id=" << id << ", value=" << name << '\n';
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
register_routes();
|
||||||
|
drogon::app().addListener(settings_.host, settings_.port);
|
||||||
|
printInfo();
|
||||||
|
drogon::app().run();
|
||||||
|
return 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
void Application::printInfo() const noexcept {
|
||||||
|
std::cout << std::format("Server starting at http://{}:{}", settings_.host, settings_.port)
|
||||||
|
<< std::endl;
|
||||||
|
std::cout << std::format("SQLite initialize at:{}", settings_.db_path) << std::endl;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "config/settings/settings.hpp"
|
||||||
|
class Application final {
|
||||||
|
public:
|
||||||
|
explicit Application(Settings settings);
|
||||||
|
int run() const;
|
||||||
|
void printInfo() const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Settings settings_;
|
||||||
|
};
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
struct Settings {
|
||||||
|
std::string host{ "127.0.0.1" };
|
||||||
|
std::uint16_t port{ 8080 };
|
||||||
|
std::string db_path{ "auth.db" };
|
||||||
|
};
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
#include "db/sqllite_db.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
SqlliteDb::SqlliteDb(const std::string &path) {
|
||||||
|
const int rc = sqlite3_open(path.c_str(), &db_);
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
std::string message = "Failed to open SQLite database";
|
||||||
|
if(db_ != nullptr) {
|
||||||
|
message += ": ";
|
||||||
|
message += sqlite3_errmsg(db_);
|
||||||
|
closeDb();
|
||||||
|
}
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SqlliteDb::~SqlliteDb() {
|
||||||
|
closeDb();
|
||||||
|
}
|
||||||
|
|
||||||
|
SqlliteDb::SqlliteDb(SqlliteDb &&other) noexcept
|
||||||
|
: db_(std::exchange(other.db_, nullptr)) {}
|
||||||
|
|
||||||
|
SqlliteDb &SqlliteDb::operator=(SqlliteDb &&other) noexcept {
|
||||||
|
if(this != &other) {
|
||||||
|
if(db_ != nullptr) {
|
||||||
|
sqlite3_close(db_);
|
||||||
|
}
|
||||||
|
db_ = std::exchange(other.db_, nullptr);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SqlliteDb::execute(std::string_view sql) {
|
||||||
|
char *error_message = nullptr;
|
||||||
|
const int rc = sqlite3_exec(db_, sql.data(), nullptr, nullptr, &error_message);
|
||||||
|
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
std::string message = "SQLite execute failed";
|
||||||
|
if(error_message != nullptr) {
|
||||||
|
message += ": ";
|
||||||
|
message += error_message;
|
||||||
|
sqlite3_free(error_message);
|
||||||
|
} else {
|
||||||
|
message += "unknown error";
|
||||||
|
}
|
||||||
|
throw std::runtime_error(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SqlliteDb::initialize() {
|
||||||
|
execute("PRAGMA foreign_keys = ON;");
|
||||||
|
execute("PRAGMA journal_mode = WAL;");
|
||||||
|
execute("PRAGMA busy_timeout = 5000;");
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3 *SqlliteDb::native_handle() const noexcept {
|
||||||
|
return db_;
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement SqlliteDb::prepare(std::string_view sql) const {
|
||||||
|
return Statement{ db_, sql };
|
||||||
|
}
|
||||||
|
|
||||||
|
void SqlliteDb::closeDb() {
|
||||||
|
if(db_ != nullptr) {
|
||||||
|
sqlite3_close(db_);
|
||||||
|
db_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "db/statement.hpp"
|
||||||
|
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
class SqlliteDb {
|
||||||
|
public:
|
||||||
|
explicit SqlliteDb(const std::string &path);
|
||||||
|
~SqlliteDb();
|
||||||
|
|
||||||
|
SqlliteDb(const SqlliteDb &) = delete;
|
||||||
|
SqlliteDb &operator=(const SqlliteDb &) = delete;
|
||||||
|
|
||||||
|
SqlliteDb(SqlliteDb &&other) noexcept;
|
||||||
|
SqlliteDb &operator=(SqlliteDb &&other) noexcept;
|
||||||
|
|
||||||
|
void execute(std::string_view sql);
|
||||||
|
void initialize();
|
||||||
|
|
||||||
|
Statement prepare(std::string_view sql) const;
|
||||||
|
|
||||||
|
sqlite3 *native_handle() const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void closeDb();
|
||||||
|
|
||||||
|
private:
|
||||||
|
sqlite3 *db_{ nullptr };
|
||||||
|
};
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
#include "db/statement.hpp"
|
||||||
|
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
Statement::Statement(sqlite3 *db, std::string_view sql) {
|
||||||
|
const int rc = sqlite3_prepare_v2(db, sql.data(), static_cast<int>(sql.size()), &stmt_, nullptr);
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
throw std::runtime_error("Failed to prepare SQLite statement");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement::~Statement() {
|
||||||
|
delete_stament();
|
||||||
|
}
|
||||||
|
|
||||||
|
Statement::Statement(Statement &&other) noexcept
|
||||||
|
: stmt_(std::exchange(other.stmt_, nullptr)) {}
|
||||||
|
|
||||||
|
Statement &Statement::operator=(Statement &&other) noexcept {
|
||||||
|
if(this != &other) {
|
||||||
|
delete_stament();
|
||||||
|
stmt_ = std::exchange(other.stmt_, nullptr);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Statement::delete_stament() {
|
||||||
|
if(stmt_ != nullptr) {
|
||||||
|
sqlite3_finalize(stmt_);
|
||||||
|
stmt_ = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Statement::bind_int64(int index, std::int64_t value) {
|
||||||
|
const int rc = sqlite3_bind_int64(stmt_, index, value);
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
throw std::runtime_error("Failed bind int64");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Statement::bind_text(int index, std::string_view value) {
|
||||||
|
const int rc = sqlite3_bind_text(stmt_, index, value.data(), static_cast<int>(value.size()),
|
||||||
|
SQLITE_TRANSIENT);
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
throw std::runtime_error("Failed bind text");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Statement::bind_null(int index) {
|
||||||
|
const int rc = sqlite3_bind_null(stmt_, index);
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
throw std::runtime_error("Failed bind null");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Statement::step() {
|
||||||
|
const int rc = sqlite3_step(stmt_);
|
||||||
|
if(rc == SQLITE_ROW) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(rc == SQLITE_DONE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Failed to step SQLite statement");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Statement::execute() {
|
||||||
|
const int rc = sqlite3_step(stmt_);
|
||||||
|
if(rc != SQLITE_DONE) {
|
||||||
|
throw std::runtime_error("Failed to execute statement");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::int64_t Statement::column_int64(int index) const {
|
||||||
|
return sqlite3_column_int64(stmt_, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Statement::column_text(int index) const {
|
||||||
|
const auto *txt = reinterpret_cast<const char *>(sqlite3_column_text(stmt_, index));
|
||||||
|
if(txt == nullptr) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return std::string{ txt };
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Statement::column_is_null(int index) const {
|
||||||
|
return sqlite3_column_type(stmt_, index) == SQLITE_NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Statement::reset() {
|
||||||
|
const int rc = sqlite3_reset(stmt_);
|
||||||
|
if(rc != SQLITE_OK) {
|
||||||
|
throw std::runtime_error("Failed reset statement");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
|
class Statement {
|
||||||
|
public:
|
||||||
|
Statement(sqlite3 *db, std::string_view sql);
|
||||||
|
~Statement();
|
||||||
|
|
||||||
|
Statement(const Statement &) = delete;
|
||||||
|
Statement &operator=(const Statement &) = delete;
|
||||||
|
|
||||||
|
Statement(Statement &&other) noexcept;
|
||||||
|
Statement &operator=(Statement &&other) noexcept;
|
||||||
|
|
||||||
|
void bind_int64(int index, std::int64_t value);
|
||||||
|
void bind_text(int inxex, std::string_view value);
|
||||||
|
void bind_null(int index);
|
||||||
|
|
||||||
|
bool step();
|
||||||
|
void execute();
|
||||||
|
|
||||||
|
std::int64_t column_int64(int index) const;
|
||||||
|
std::string column_text(int index) const;
|
||||||
|
bool column_is_null(int index) const;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void delete_stament();
|
||||||
|
|
||||||
|
private:
|
||||||
|
sqlite3_stmt *stmt_{ nullptr };
|
||||||
|
};
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#include "http/controllers/health_controller.hpp"
|
||||||
|
|
||||||
|
#include <drogon/drogon.h>
|
||||||
|
#include <json/json.h>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
void HealthController::handle(
|
||||||
|
const drogon::HttpRequestPtr &,
|
||||||
|
std::function<void(const drogon::HttpResponsePtr &)> &&callback) const {
|
||||||
|
Json::Value body;
|
||||||
|
body["status"] = "ok";
|
||||||
|
auto response = drogon::HttpResponse::newHttpJsonResponse(body);
|
||||||
|
response->setStatusCode(drogon::k200OK);
|
||||||
|
callback(response);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <drogon/HttpController.h>
|
||||||
|
|
||||||
|
class HealthController {
|
||||||
|
public:
|
||||||
|
void handle(const drogon::HttpRequestPtr &req,
|
||||||
|
std::function<void(const drogon::HttpResponsePtr &)> &&callback) const;
|
||||||
|
void testFor() {}
|
||||||
|
};
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include "application/application.hpp"
|
||||||
|
#include "config/settings/settings.hpp"
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
Settings s;
|
||||||
|
Application app(s);
|
||||||
|
return app.run();
|
||||||
|
}
|
||||||
Submodule
+1
Submodule submodules/Catch2 added at 1df10d28ae
Submodule
+1
Submodule submodules/drogon added at acad9c8ee7
Submodule
+1
Submodule submodules/json added at 9a737481ae
@@ -0,0 +1,6 @@
|
|||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
TEST_CASE("smoke test")
|
||||||
|
{
|
||||||
|
REQUIRE(1 + 1 == 2);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user