ores.storage.service
Table of Contents
1. Summary
ores.storage.service is the process that lets a component reach storage over
the bus. It binds the operation set's subjects, authenticates the caller and
checks the operation's permission code before it acts, and calls
ores.storage.core to move the bytes.
2. Inputs
- The bus endpoint and the service's own configuration.
- An authenticated request on one of the operation set's subjects.
3. Outputs
- One reply per request, carrying the protocol's
resultand, where the operation returns data, the object's metadata or page.
4. Entry points
src/main.cpp— the process entry point.include/ores.storage.service/messaging/registrar.hpp— the handler registration.
5. Dependencies
- ores.storage.core — the implementation it serves.
ores.service— the domain service runner every service shares.ores.nats— the transport.
6. Implementation
ores.storage/service is the first service past the ores.cpp.service-app
stub, so its implementation lives in its own model rather than in the generated
src/app/application.cpp. Each block below fills one paste point of
ores.cpp.service-app.application_impl; the run body suppresses the stub.
6.1. Extra includes
#include "ores.nats/service/client.hpp" #include "ores.service/service/domain_service_runner.hpp" #include "ores.service/service/heartbeat_publisher.hpp" #include "ores.storage.core/filesystem/local_store.hpp" #include "ores.storage.service/messaging/registrar.hpp" #include <boost/asio/co_spawn.hpp> #include <boost/asio/detached.hpp> #include <memory> #include <utility>
6.2. Namespace preamble
namespace { constexpr std::string_view service_name = "ores.storage.service"; constexpr std::string_view service_version = ORES_VERSION; }
6.3. Run body
The store is the one the HTTP routes are given: two front doors onto the same tree, which is what makes a put over the bus and a put over HTTP leave the same object.
BOOST_LOG_SEV(lg(), info) << ores::utility::version::format_startup_message( "ores.storage.service", 0, 1); ores::nats::service::client nats(cfg.nats); nats.connect(); // The store is the one the HTTP routes are given: two front doors onto the // same tree, which is what makes a put over the bus and a put over HTTP // leave the same object. ores::storage::filesystem::local_store store(cfg.storage_dir); // Bound before the await, so no lambda of the call lives in this frame; see run(). auto service_run = ores::service::service::run( io_ctx, nats, make_context(cfg.database), "ores.storage.service", [store](auto& n, auto c, auto v) { return ores::storage::service::messaging::registrar::register_handlers( n, std::move(c), std::move(v), store); }, [&nats](boost::asio::io_context& ioc) { auto hb = std::make_shared<ores::service::service::heartbeat_publisher>( std::string(service_name), std::string(service_version), nats); boost::asio::co_spawn(ioc, [hb]() { return hb->run(); }, boost::asio::detached); }); co_await std::move(service_run); co_return;
7. Options
The options this service takes beyond logging, NATS and the database. Codegen writes the member, its wire field, its command-line declaration and its assignment from each entry.
7.1. storage_dir
Root directory the buckets live under.
It must be the same directory the HTTP storage routes are given, because the two interfaces serve the same objects through the same store.
8. See also
- ores.storage — the component group overview.
The service instantiates the wire codecs its handlers carry, and
ores.utility only exposes them: it instantiates none of the templates itself,
so --as-needed drops msgpack-c from the utility's DT_NEEDED and the service
fails at load with an undefined msgpack-c symbol. The carrier is linked
where it is used.
find_package(msgpack-c CONFIG REQUIRED)
target_link_libraries(${lib_target_name}
PUBLIC
msgpack-c)
target_link_libraries(${tests_target_name}
PRIVATE
${lib_target_name}
ores.testing.lib
ores.logging.lib
Catch2::Catch2
faker-cxx::faker-cxx
ores.openssl_cleanup
Threads::Threads)