cpp-msgpack-rpc 0.2.0
An RPC library implementing MessagePack RPC.
Loading...
Searching...
No Matches
tcp_acceptor_factory.h
Go to the documentation of this file.
1/*
2 * Copyright 2023 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <cstdint>
23#include <memory>
24#include <optional>
25#include <string>
26#include <string_view>
27#include <utility>
28#include <vector>
29
30#include <asio/error_code.hpp>
31#include <asio/ip/basic_endpoint.hpp>
32#include <asio/ip/basic_resolver_entry.hpp>
33#include <asio/ip/basic_resolver_iterator.hpp>
34#include <asio/ip/tcp.hpp>
35#include <fmt/format.h>
36#include <fmt/ostream.h>
37
51
53
57class TCPAcceptorFactory final : public IAcceptorFactory {
58public:
60 using AsioResolver = asio::ip::tcp::resolver;
61
64
67
75 TCPAcceptorFactory(std::shared_ptr<executors::IExecutor> executor,
76 const config::MessageParserConfig& message_parser_config,
77 std::shared_ptr<logging::Logger> logger)
78 : executor_(std::move(executor)),
79 message_parser_config_(message_parser_config),
80 resolver_(executor_->context(executors::OperationType::TRANSPORT)),
81 scheme_("tcp"),
82 log_name_(fmt::format("AcceptorFactory({})", scheme_)),
83 logger_(std::move(logger)) {}
84
86 std::vector<std::shared_ptr<IAcceptor>> create(
87 const addresses::URI& uri) override {
88 const auto resolved_endpoints = resolve(uri);
89
90 std::vector<std::shared_ptr<IAcceptor>> acceptors;
91 acceptors.reserve(resolved_endpoints.size());
92 for (const auto& entry : resolved_endpoints) {
93 const auto local_address = ConcreteAddress(entry.endpoint());
94 std::shared_ptr<IAcceptor> acceptor =
95 std::make_shared<AcceptorType>(
97 acceptors.push_back(std::move(acceptor));
98 }
99
100 return acceptors;
101 }
102
103private:
110 [[nodiscard]] AsioResolver::results_type resolve(
111 const addresses::URI& uri) {
112 if (uri.scheme() != scheme_) {
113 throw MsgpackRPCException(StatusCode::INVALID_ARGUMENT,
114 fmt::format("Scheme is different with the resolver: "
115 "expected={}, actual={}",
116 scheme_, uri.scheme()));
117 }
118
119 MSGPACK_RPC_TRACE(logger_, "({}) Resolve {}.", log_name_, uri);
120
121 const std::string service = fmt::format(
122 "{}", uri.port_number().value_or(static_cast<std::uint16_t>(0)));
123 asio::error_code error;
124 auto results = resolver_.resolve(uri.host_or_path(), service, error);
125 if (error) {
126 const auto message =
127 fmt::format("Failed to resolve {}: {}", uri, error.message());
128 MSGPACK_RPC_ERROR(logger_, "({}) {}", log_name_, message);
129 throw MsgpackRPCException(StatusCode::HOST_UNRESOLVED, message);
130 }
131
132 if (logger_->output_log_level() <= logging::LogLevel::TRACE) {
133 for (const auto& result : results) {
134 MSGPACK_RPC_TRACE(logger_, "({}) Result of resolving {}: {}.",
135 log_name_, uri, fmt::streamed(result.endpoint()));
136 }
137 }
138
139 return results;
140 }
141
143 std::shared_ptr<executors::IExecutor> executor_;
144
147
150
152 std::string scheme_;
153
155 std::string log_name_;
156
158 std::shared_ptr<logging::Logger> logger_;
159};
160
161} // namespace msgpack_rpc::transport::tcp
Definition of Acceptor class.
Class of addresses of TCP.
Definition tcp_address.h:44
Class of URIs (Uniform Resource Identifiers) to specify endpoints in this library.
Definition uri.h:38
std::string_view scheme() const noexcept
Get the scheme.
Definition uri.cpp:38
std::optional< std::uint16_t > port_number() const noexcept
Get the port number.
Definition uri.cpp:42
std::string_view host_or_path() const noexcept
Get the host name or file path.
Definition uri.cpp:40
Class of exceptions in cpp-msgpack-rpc library.
Class of configuration of parsers of messages.
tcp::TCPAcceptor AcceptorType
Type of acceptors.
std::shared_ptr< executors::IExecutor > executor_
Executor.
AsioResolver::results_type resolve(const addresses::URI &uri)
Resolve a URI.
std::shared_ptr< logging::Logger > logger_
Logger.
addresses::TCPAddress ConcreteAddress
Type of concrete addresses.
std::string log_name_
Name of the connection for logs.
config::MessageParserConfig message_parser_config_
Configuration of parsers of messages.
asio::ip::tcp::resolver AsioResolver
Type of resolvers in asio library.
std::vector< std::shared_ptr< IAcceptor > > create(const addresses::URI &uri) override
Create acceptors for a URI.
TCPAcceptorFactory(std::shared_ptr< executors::IExecutor > executor, const config::MessageParserConfig &message_parser_config, std::shared_ptr< logging::Logger > logger)
Constructor.
Definition of IAcceptor class.
Definition of IAcceptorFactory class.
Definition of IExecutor class.
Definition of LogLevel enumeration.
Definition of Logger class.
#define MSGPACK_RPC_TRACE(LOGGER_PTR,...)
Write a trace log.
Definition logger.h:174
#define MSGPACK_RPC_ERROR(LOGGER_PTR,...)
Write a error log.
Definition logger.h:222
Definition of MessageParserConfig class.
Definition of MsgpackRPCException class.
Namespace of fmt library.
Definition uri.h:113
Namespace of executors to process asynchronous tasks.
@ TRACE
Trace. (Internal operations to send and receive messages.)
Definition log_level.h:31
Namespace of transport of messages via TCP.
Acceptor< asio::ip::tcp::acceptor, asio::ip::tcp::socket, addresses::TCPAddress > TCPAcceptor
Type of acceptors of TCP.
STL namespace.
Definition of OperationType enumeration.
Definition of StatusCode enumeration.
Definition of TCPAcceptor type.
Definition of TCPAddress.
Definition of URI class.