diff --git a/api/api-doc/storage_service.json b/api/api-doc/storage_service.json new file mode 100644 index 0000000000..e45d6de89c --- /dev/null +++ b/api/api-doc/storage_service.json @@ -0,0 +1,29 @@ +{ + "apiVersion":"0.0.1", + "swaggerVersion":"1.2", + "basePath":"{{Protocol}}://{{Host}}", + "resourcePath":"/storage_service", + "produces":[ + "application/json" + ], + "apis":[ + { + "path":"/storage_service/hostid/local", + "operations":[ + { + "method":"GET", + "summary":"Returns the local host id", + "type":"string", + "nickname":"local_hostid", + "produces":[ + "application/json" + ], + "parameters":[ + { + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/api/api.cc b/api/api.cc new file mode 100644 index 0000000000..40f5022816 --- /dev/null +++ b/api/api.cc @@ -0,0 +1,24 @@ +/* + * Copyright 2015 Cloudius Systems + */ + +#include "api.hh" +#include "http/api_docs.hh" +#include "storage_service.hh" + +namespace api { + +future<> set_server(http_context& ctx) { + auto rb = std::make_shared < api_registry_builder > ("api/api-doc/"); + + return ctx.http_server.set_routes(rb->set_api_doc()).then([&ctx, rb] { + ctx.http_server.set_routes(rb->register_function("storage_service", + "The storage service API")) + .then([&ctx] { + return set_storage_service(ctx); + }); + }); +} + +} + diff --git a/api/api.hh b/api/api.hh new file mode 100644 index 0000000000..dffad12346 --- /dev/null +++ b/api/api.hh @@ -0,0 +1,20 @@ +/* + * Copyright 2015 Cloudius Systems + */ + +#ifndef API_API_HH_ +#define API_API_HH_ + +#include "http/httpd.hh" + +namespace api { + +struct http_context { + http_server_control http_server; +}; + +future<> set_server(http_context& ctx); + +} + +#endif /* API_API_HH_ */ diff --git a/api/storage_service.cc b/api/storage_service.cc new file mode 100644 index 0000000000..86b6a26e1a --- /dev/null +++ b/api/storage_service.cc @@ -0,0 +1,18 @@ +/* + * Copyright 2015 Cloudius Systems + */ + +#include "storage_service.hh" +#include "api/api-doc/storage_service.json.hh" + +namespace api { + +future<> set_storage_service(http_context& ctx) { + return ctx.http_server.set_routes([] (routes& r) { + httpd::storage_service_json::local_hostid.set(r, [](const_req req) { + return ""; + }); + }); +} + +} diff --git a/api/storage_service.hh b/api/storage_service.hh new file mode 100644 index 0000000000..d17d679e27 --- /dev/null +++ b/api/storage_service.hh @@ -0,0 +1,16 @@ +/* + * Copyright 2015 Cloudius Systems + */ + +#ifndef API_STORAGE_SERVICE_HH_ +#define API_STORAGE_SERVICE_HH_ + +#include "api.hh" + +namespace api { + +future<> set_storage_service(http_context& ctx); + +} + +#endif /* API_APP_HH_ */ diff --git a/configure.py b/configure.py index 5bde80474f..8ed5bbb2a9 100755 --- a/configure.py +++ b/configure.py @@ -259,6 +259,11 @@ http = ['http/transformers.cc', 'http/request_parser.rl', 'http/api_docs.cc', ] + +api = ['api/api.cc', + 'api/api-doc/storage_service.json', + 'api/storage_service.cc', + ] defines = [] libs = '-laio -lboost_program_options -lboost_system -lstdc++ -lm -lboost_unit_test_framework -lboost_thread -lcryptopp -lrt' hwloc_libs = '-lhwloc -lnuma -lpciaccess -lxml2 -lz' @@ -370,7 +375,7 @@ urchin_core = (['database.cc', deps = { 'libseastar.a' : core + libnet, 'seastar.pc': [], - 'seastar': ['main.cc'] + urchin_core, + 'seastar': ['main.cc'] + http + api + urchin_core, 'tests/test-reactor': ['tests/test-reactor.cc'] + core, 'apps/httpd/httpd': ['apps/httpd/demo.json', 'apps/httpd/main.cc'] + http + libnet + core, 'apps/memcached/memcached': ['apps/memcached/memcache.cc'] + memcache_base, diff --git a/main.cc b/main.cc index 902fb5c7f2..93d7ad881a 100644 --- a/main.cc +++ b/main.cc @@ -8,6 +8,8 @@ #include "core/distributed.hh" #include "thrift/server.hh" #include "transport/server.hh" +#include "http/httpd.hh" +#include "api/api.hh" namespace bpo = boost::program_options; @@ -16,18 +18,21 @@ int main(int ac, char** av) { app.add_options() ("cql-port", bpo::value()->default_value(9042), "CQL port") ("thrift-port", bpo::value()->default_value(9160), "Thrift port") + ("api-port", bpo::value()->default_value(10000), "Http Rest API port") ("datadir", bpo::value()->default_value("/var/lib/cassandra/data"), "data directory"); auto server = std::make_unique>(); distributed db; distributed qp; service::storage_proxy proxy{db}; + api::http_context ctx; return app.run(ac, av, [&] { auto&& config = app.configuration(); uint16_t thrift_port = config["thrift-port"].as(); uint16_t cql_port = config["cql-port"].as(); sstring datadir = config["datadir"].as(); + uint16_t api_port = config["api-port"].as(); return db.start().then([datadir, &db] { engine().at_exit([&db] { return db.stop(); }); @@ -49,6 +54,14 @@ int main(int ac, char** av) { }).then([thrift_port] { std::cout << "Thrift server listening on port " << thrift_port << " ...\n"; }); + }).then([&db, api_port, &ctx]{ + ctx.http_server.start().then([api_port, &ctx] { + return set_server(ctx); + }).then([&ctx, api_port] { + ctx.http_server.listen(api_port); + }).then([api_port] { + std::cout << "Seastar HTTP server listening on port " << api_port << " ...\n"; + }); }).or_terminate(); }); }