20#ifndef ORES_TRADING_MESSAGING_INSTRUMENT_REF_HANDLER_HPP
21#define ORES_TRADING_MESSAGING_INSTRUMENT_REF_HANDLER_HPP
24#include "ores.logging/make_logger.hpp"
25#include "ores.nats/domain/message.hpp"
26#include "ores.nats/service/client.hpp"
27#include "ores.database/domain/context.hpp"
28#include "ores.security/jwt/jwt_authenticator.hpp"
29#include "ores.service/messaging/handler_helpers.hpp"
30#include "ores.service/service/request_context.hpp"
31#include "ores.trading.api/messaging/day_count_fraction_type_protocol.hpp"
32#include "ores.trading.api/messaging/business_day_convention_type_protocol.hpp"
33#include "ores.trading.api/messaging/floating_index_type_protocol.hpp"
34#include "ores.trading.api/messaging/payment_frequency_type_protocol.hpp"
35#include "ores.trading.api/messaging/leg_type_protocol.hpp"
36#include "ores.trading.core/service/day_count_fraction_type_service.hpp"
37#include "ores.trading.core/service/business_day_convention_type_service.hpp"
38#include "ores.trading.core/service/floating_index_type_service.hpp"
39#include "ores.trading.core/service/payment_frequency_type_service.hpp"
40#include "ores.trading.core/service/leg_type_service.hpp"
41#include "ores.utility/uuid/tenant_id.hpp"
43namespace ores::trading::messaging {
46inline auto& instrument_ref_handler_lg() {
47 static auto instance = ores::logging::make_logger(
48 "ores.trading.messaging.instrument_ref_handler");
53using ores::service::messaging::reply;
54using ores::service::messaging::decode;
55using ores::service::messaging::error_reply;
56using ores::service::messaging::has_permission;
59class instrument_ref_handler {
63 std::optional<ores::security::jwt::jwt_authenticator> verifier)
64 : nats_(nats), ctx_(
std::move(ctx)), verifier_(
std::move(verifier)) {}
67 template<
typename Svc,
typename Req,
typename Resp>
69 BOOST_LOG_SEV(instrument_ref_handler_lg(), debug) <<
"Handling " << msg.
subject;
70 auto req_ctx_expected = ores::service::service::make_request_context(
71 ctx_, msg, verifier_);
72 if (!req_ctx_expected) {
73 error_reply(nats_, msg, req_ctx_expected.error());
76 const auto& req_ctx = *req_ctx_expected;
77 const auto sys_ctx = req_ctx.with_tenant(
82 resp.types = svc.list_types();
83 resp.total_available_count =
static_cast<int>(resp.types.size());
85 BOOST_LOG_SEV(instrument_ref_handler_lg(), debug) <<
"Completed " << msg.
subject;
86 reply(nats_, msg, resp);
89 template<
typename Svc,
typename Req,
typename Resp>
91 BOOST_LOG_SEV(instrument_ref_handler_lg(), debug) <<
"Handling " << msg.
subject;
92 auto req_ctx_expected = ores::service::service::make_request_context(
93 ctx_, msg, verifier_);
94 if (!req_ctx_expected) {
95 error_reply(nats_, msg, req_ctx_expected.error());
98 const auto& req_ctx = *req_ctx_expected;
99 if (!has_permission(req_ctx,
"trading::instruments:write")) {
104 if (
auto req = decode<Req>(msg)) {
106 svc.save_type(req->data);
107 BOOST_LOG_SEV(instrument_ref_handler_lg(), debug)
108 <<
"Completed " << msg.
subject;
109 reply(nats_, msg, Resp{.success =
true});
110 }
catch (
const std::exception& e) {
111 BOOST_LOG_SEV(instrument_ref_handler_lg(), error)
112 << msg.
subject <<
" failed: " << e.what();
113 reply(nats_, msg, Resp{.success =
false, .message = e.what()});
116 BOOST_LOG_SEV(instrument_ref_handler_lg(), warn)
117 <<
"Failed to decode: " << msg.
subject;
121 template<
typename Svc,
typename Req,
typename Resp>
123 BOOST_LOG_SEV(instrument_ref_handler_lg(), debug) <<
"Handling " << msg.
subject;
124 auto req_ctx_expected = ores::service::service::make_request_context(
125 ctx_, msg, verifier_);
126 if (!req_ctx_expected) {
127 error_reply(nats_, msg, req_ctx_expected.error());
130 const auto& req_ctx = *req_ctx_expected;
131 if (!has_permission(req_ctx,
"trading::instruments:delete")) {
136 if (
auto req = decode<Req>(msg)) {
138 svc.remove_types(req->codes);
139 BOOST_LOG_SEV(instrument_ref_handler_lg(), debug)
140 <<
"Completed " << msg.
subject;
141 reply(nats_, msg, Resp{.success =
true});
142 }
catch (
const std::exception& e) {
143 BOOST_LOG_SEV(instrument_ref_handler_lg(), error)
144 << msg.
subject <<
" failed: " << e.what();
145 reply(nats_, msg, Resp{.success =
false, .message = e.what()});
148 BOOST_LOG_SEV(instrument_ref_handler_lg(), warn)
149 <<
"Failed to decode: " << msg.
subject;
153 template<
typename Svc,
typename Req,
typename Resp>
155 BOOST_LOG_SEV(instrument_ref_handler_lg(), debug) <<
"Handling " << msg.
subject;
156 auto req_ctx_expected = ores::service::service::make_request_context(
157 ctx_, msg, verifier_);
158 if (!req_ctx_expected) {
159 error_reply(nats_, msg, req_ctx_expected.error());
162 const auto& req_ctx = *req_ctx_expected;
163 const auto sys_ctx = req_ctx.with_tenant(
166 if (
auto req = decode<Req>(msg)) {
168 auto hist = svc.get_type_history(req->code);
169 BOOST_LOG_SEV(instrument_ref_handler_lg(), debug)
170 <<
"Completed " << msg.
subject;
171 reply(nats_, msg, Resp{.success =
true, .history = std::move(hist)});
172 }
catch (
const std::exception& e) {
173 BOOST_LOG_SEV(instrument_ref_handler_lg(), error)
174 << msg.
subject <<
" failed: " << e.what();
175 reply(nats_, msg, Resp{.success =
false, .message = e.what()});
178 BOOST_LOG_SEV(instrument_ref_handler_lg(), warn)
179 <<
"Failed to decode: " << msg.
subject;
186 list_impl<service::day_count_fraction_type_service,
187 get_day_count_fraction_types_request,
188 get_day_count_fraction_types_response>(std::move(msg));
191 save_impl<service::day_count_fraction_type_service,
192 save_day_count_fraction_type_request,
193 save_day_count_fraction_type_response>(std::move(msg));
196 delete_impl<service::day_count_fraction_type_service,
197 delete_day_count_fraction_type_request,
198 delete_day_count_fraction_type_response>(std::move(msg));
201 history_impl<service::day_count_fraction_type_service,
202 get_day_count_fraction_type_history_request,
203 get_day_count_fraction_type_history_response>(std::move(msg));
208 list_impl<service::business_day_convention_type_service,
209 get_business_day_convention_types_request,
210 get_business_day_convention_types_response>(std::move(msg));
213 save_impl<service::business_day_convention_type_service,
214 save_business_day_convention_type_request,
215 save_business_day_convention_type_response>(std::move(msg));
218 delete_impl<service::business_day_convention_type_service,
219 delete_business_day_convention_type_request,
220 delete_business_day_convention_type_response>(std::move(msg));
223 history_impl<service::business_day_convention_type_service,
224 get_business_day_convention_type_history_request,
225 get_business_day_convention_type_history_response>(std::move(msg));
230 list_impl<service::floating_index_type_service,
231 get_floating_index_types_request,
232 get_floating_index_types_response>(std::move(msg));
235 save_impl<service::floating_index_type_service,
236 save_floating_index_type_request,
237 save_floating_index_type_response>(std::move(msg));
240 delete_impl<service::floating_index_type_service,
241 delete_floating_index_type_request,
242 delete_floating_index_type_response>(std::move(msg));
245 history_impl<service::floating_index_type_service,
246 get_floating_index_type_history_request,
247 get_floating_index_type_history_response>(std::move(msg));
252 list_impl<service::payment_frequency_type_service,
253 get_payment_frequency_types_request,
254 get_payment_frequency_types_response>(std::move(msg));
257 save_impl<service::payment_frequency_type_service,
258 save_payment_frequency_type_request,
259 save_payment_frequency_type_response>(std::move(msg));
262 delete_impl<service::payment_frequency_type_service,
263 delete_payment_frequency_type_request,
264 delete_payment_frequency_type_response>(std::move(msg));
267 history_impl<service::payment_frequency_type_service,
268 get_payment_frequency_type_history_request,
269 get_payment_frequency_type_history_response>(std::move(msg));
274 list_impl<service::leg_type_service,
275 get_leg_types_request,
276 get_leg_types_response>(std::move(msg));
279 save_impl<service::leg_type_service,
280 save_leg_type_request,
281 save_leg_type_response>(std::move(msg));
284 delete_impl<service::leg_type_service,
285 delete_leg_type_request,
286 delete_leg_type_response>(std::move(msg));
289 history_impl<service::leg_type_service,
290 get_leg_type_history_request,
291 get_leg_type_history_response>(std::move(msg));
297 std::optional<ores::security::jwt::jwt_authenticator> verifier_;
Implements logging infrastructure for ORE Studio.
Definition boost_severity.hpp:28
@ forbidden
The caller is authenticated but lacks the required permission.
Context for the operations on a postgres database.
Definition context.hpp:47
A received NATS message.
Definition message.hpp:40
std::string subject
The subject the message was published to.
Definition message.hpp:44
NATS client: connection, pub/sub, request/reply, and JetStream.
Definition client.hpp:73
static tenant_id system()
Creates a tenant_id representing the system tenant.
Definition tenant_id.cpp:41