Skip to content

Commit

Permalink
[EN-7490] Implement Tools
Browse files Browse the repository at this point in the history
  • Loading branch information
ttldtor committed Sep 15, 2023
1 parent 45dadc7 commit 79642d7
Show file tree
Hide file tree
Showing 7 changed files with 250 additions and 27 deletions.
9 changes: 8 additions & 1 deletion include/dxfeed_graal_cpp_api/event/EventTypeEnum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ class DXFCPP_EXPORT EventTypeEnum {
}

public:
using RefSetType =
std::unordered_set<std::reference_wrapper<const EventTypeEnum>, decltype([](auto &&eventTypeRef) {
return static_cast<std::size_t>(eventTypeRef.get().getId());
})>;

static const EventTypeEnum QUOTE;
static const EventTypeEnum PROFILE;
static const EventTypeEnum SUMMARY;
Expand Down Expand Up @@ -74,9 +79,11 @@ class DXFCPP_EXPORT EventTypeEnum {

static const std::unordered_map<std::string, std::reference_wrapper<const EventTypeEnum>> ALL_BY_CLASS_NAME;

explicit EventTypeEnum() noexcept : EventTypeEnum{static_cast<std::uint32_t>(-1), "INVALID", "Invalid", false} {
EventTypeEnum() noexcept : EventTypeEnum{static_cast<std::uint32_t>(-1), "INVALID", "Invalid", false} {
}

virtual ~EventTypeEnum() noexcept = default;

/**
* @return The dxFeed Graal Native C-API event class id
*/
Expand Down
160 changes: 137 additions & 23 deletions include/dxfeed_graal_cpp_api/internal/utils/CmdArgsUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@

#include "../Conf.hpp"

#include "../../event/EventTypeEnum.hpp"

#include <cstddef>
#include <cstdint>
#include <optional>
#include <string>
#include <type_traits>
#include <unordered_set>

namespace dxfcpp {

class EventTypeEnum;

struct DXFCPP_EXPORT CmdArgsUtils final {
/**
* Parses an input string and returns a set of symbols.
Expand All @@ -24,6 +25,40 @@ struct DXFCPP_EXPORT CmdArgsUtils final {
*/
static std::unordered_set<std::string> parseSymbols(const std::string &symbols) noexcept;

/**
* Parses an input string and returns a set of symbols.
*
* @param symbols The coma-separated list of symbols.
* @return The created set of parsed symbols.
*/
static std::unordered_set<std::string> parseSymbols(const char *symbols) noexcept {
return parseSymbols(std::string(symbols));
}

/**
* Parses an input string and returns a set of symbols.
*
* @param symbols The coma-separated list of symbols.
* @return The created set of parsed symbols.
*/
static std::unordered_set<std::string> parseSymbols(std::string_view symbols) noexcept {
return parseSymbols(symbols.data());
}

/**
* Parses an input string and returns a set of symbols.
*
* @param symbols The coma-separated list of symbols.
* @return The created set of parsed symbols.
*/
static std::unordered_set<std::string> parseSymbols(std::optional<std::string> symbols) noexcept {
if (symbols.has_value()) {
return parseSymbols(symbols.value());
}

return {};
}

/**
* Parses an input string and returns a set of event types.
*
Expand All @@ -33,6 +68,35 @@ struct DXFCPP_EXPORT CmdArgsUtils final {
static std::unordered_set<std::reference_wrapper<const EventTypeEnum>>
parseTypes(const std::string &types) noexcept;

/**
* Parses an input string and returns a set of event types.
*
* @param types The comma-separated list of event types.
* @return The created set of parsed types.
*/
static std::unordered_set<std::reference_wrapper<const EventTypeEnum>> parseTypes(const char *types) noexcept {
return parseTypes(std::string(types));
}

/**
* Parses an input string and returns a set of event types.
*
* @param types The comma-separated list of event types.
* @return The created set of parsed types.
*/
static std::unordered_set<std::reference_wrapper<const EventTypeEnum>> parseTypes(std::string_view types) noexcept {
return parseTypes(types.data());
}

/**
* Parses an input string and returns a set of event types.
*
* @param types The comma-separated list of event types.
* @return The created set of parsed types.
*/
static std::unordered_set<std::reference_wrapper<const EventTypeEnum>>
parseTypes(std::optional<std::string> types) noexcept;

/**
* Parses the input collection of strings and returns a collection of key-value properties.
* The input strings should look like comma-separated: "key=value".
Expand All @@ -41,35 +105,85 @@ struct DXFCPP_EXPORT CmdArgsUtils final {
* @return The collection of key-value properties.
*/
static std::unordered_map<std::string, std::string> parseProperties(const std::string &properties) noexcept;
};

/**
* Parses Date+Time string and converts to timestamp
*
* @param string Date+Time string
* @return UTC timestamp
*/
DXFCPP_EXPORT std::int64_t parseDateTime(const std::string &string) noexcept;
/**
* Parses the input collection of strings and returns a collection of key-value properties.
* The input strings should look like comma-separated: "key=value".
*
* @param properties The input comma-separated key-value pairs.
* @return The collection of key-value properties.
*/
static std::unordered_map<std::string, std::string> parseProperties(const char *properties) noexcept {
return parseProperties(std::string(properties));
}

struct Arg {};
/**
* Parses the input collection of strings and returns a collection of key-value properties.
* The input strings should look like comma-separated: "key=value".
*
* @param properties The input comma-separated key-value pairs.
* @return The collection of key-value properties.
*/
static std::unordered_map<std::string, std::string> parseProperties(std::string_view properties) noexcept {
return parseProperties(properties.data());
}

struct ValueArg {};
/**
* Parses the input collection of strings and returns a collection of key-value properties.
* The input strings should look like comma-separated: "key=value".
*
* @param properties The input comma-separated key-value pairs.
* @return The collection of key-value properties.
*/
static std::unordered_map<std::string, std::string>
parseProperties(std::optional<std::string> properties) noexcept {
if (properties.has_value()) {
return parseProperties(properties.value());
}

return {};
}

/**
* Parses Date+Time string and converts to timestamp
*
* @param string Date+Time string
* @return UTC timestamp
*/
static std::int64_t parseDateTime(const std::string &string) noexcept;

struct AddressArg : ValueArg {
[[nodiscard]] std::string getName() const noexcept {
return "address";
/**
* Parses Date+Time string and converts to timestamp
*
* @param string Date+Time string
* @return UTC timestamp
*/
static std::int64_t parseDateTime(const char *string) noexcept {
return parseDateTime(std::string(string));
}

[[nodiscard]] std::string getShortDescription() const noexcept {
return
R"(
The address(es) to connect to retrieve data (see "Help address").
For Token-Based Authorization, use the following format: "<address>:<port>[login=entitle:<token>]".
)";
/**
* Parses Date+Time string and converts to timestamp
*
* @param string Date+Time string
* @return UTC timestamp
*/
static std::int64_t parseDateTime(std::string_view string) noexcept {
return parseDateTime(string.data());
}

[[nodiscard]] std::string parse(const std::string& s) const noexcept{
return s;
/**
* Parses Date+Time string and converts to timestamp
*
* @param string Date+Time string
* @return UTC timestamp
*/
static std::int64_t parseDateTime(std::optional<std::string> string) noexcept {
if (string.has_value()) {
return parseDateTime(string.value());
}

return -1;
}
};

Expand Down
2 changes: 1 addition & 1 deletion samples/cpp/DxFeedConnect/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ int main(int argc, char *argv[]) {
auto time = -1ULL;

if (argc >= 5) {
time = parseDateTime(argv[4]);
time = CmdArgsUtils::parseDateTime(argv[4]);
}

// Create an endpoint and connect to specified address.
Expand Down
19 changes: 18 additions & 1 deletion src/internal/utils/CmdArgsUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ decltype(ranges::views::transform([](auto &&s) {
})) transformToUpper{};

std::unordered_set<std::string> CmdArgsUtils::parseSymbols(const std::string &symbols) noexcept {
if (symbols.empty()) {
return {};
}

std::unordered_set<std::string> result{};

auto addSymbol = [&result](auto &&symbol) {
Expand Down Expand Up @@ -117,6 +121,10 @@ std::unordered_set<std::string> CmdArgsUtils::parseSymbols(const std::string &sy

std::unordered_set<std::reference_wrapper<const EventTypeEnum>>
CmdArgsUtils::parseTypes(const std::string &types) noexcept {
if (types.empty()) {
return {};
}

auto split = splitAndTrim(types) | filterNonEmpty;
auto allByName = split | transformToUpper | ranges::views::filter([](const auto &s) {
return EventTypeEnum::ALL_BY_NAME.contains(s);
Expand All @@ -135,6 +143,15 @@ CmdArgsUtils::parseTypes(const std::string &types) noexcept {
ranges::to<std::unordered_set<std::reference_wrapper<const EventTypeEnum>>>();
}

std::unordered_set<std::reference_wrapper<const EventTypeEnum>>
CmdArgsUtils::parseTypes(std::optional<std::string> types) noexcept {
if (types.has_value()) {
return parseTypes(types.value());
}

return std::unordered_set<std::reference_wrapper<const EventTypeEnum>>{};
}

std::unordered_map<std::string, std::string> CmdArgsUtils::parseProperties(const std::string &properties) noexcept {
auto p = trimStr(properties);

Expand All @@ -154,7 +171,7 @@ std::unordered_map<std::string, std::string> CmdArgsUtils::parseProperties(const
ranges::to<std::unordered_map<std::string, std::string>>();
}

std::int64_t parseDateTime(const std::string &string) noexcept {
std::int64_t CmdArgsUtils::parseDateTime(const std::string &string) noexcept {
const static auto dateFormats = {
"%Y%m%d", "%Y-%m-%d",
// "%Y\\%m\\%d",
Expand Down
81 changes: 81 additions & 0 deletions tools/Tools/src/Connect/ConnectTool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,18 @@

#include <chrono>
#include <cstdint>
#include <iostream>
#include <memory>
#include <utility>
#include <variant>

#include <fmt/chrono.h>
#include <fmt/format.h>
#include <fmt/ostream.h>
#include <fmt/std.h>

#include <range/v3/all.hpp>

namespace dxfcpp::tools {

struct ConnectTool {
Expand All @@ -36,8 +44,81 @@ struct ConnectTool {
return {};
}

struct Args {
std::string address;
std::optional<std::string> types;
std::optional<std::string> symbols;
std::optional<std::string> fromTime;
std::optional<std::string> source;
std::optional<std::string> properties;
std::optional<std::string> tape;
bool isQuite;

static Args parse(const std::vector<std::string> &args) noexcept {
return {};
}
};

template <typename Args> void run(Args &&args) {
using namespace std::literals;

auto endpoint =
DXEndpoint::newBuilder()
->withRole(DXEndpoint::Role::FEED)
->withProperties(CmdArgsUtils::parseProperties(args.properties))
->withName(getName() + "Tool")
->build();

std::shared_ptr<DXFeedSubscription> sub = endpoint->getFeed()->createSubscription(
CmdArgsUtils::parseTypes(args.types));

if (!args.isQuite) {
sub->addEventListener([](auto &&events) {
for (auto &&e : events) {
std::cout << e << "\n";
}

std::cout.flush();
});
}

auto symbols = CmdArgsUtils::parseSymbols(args.symbols) | ranges::to<std::unordered_set<SymbolWrapper>>;

if (args.fromTime.has_value()) {
auto fromTime = CmdArgsUtils::parseDateTime(args.fromTime.value());

symbols = symbols | ranges::views::transform([fromTime](const auto &sw) {
return TimeSeriesSubscriptionSymbol{sw, fromTime};
}) |
ranges::to<std::unordered_set<SymbolWrapper>>;
} else if (args.source.has_value()) {
auto source = OrderSource::valueOf(args.source.value());

symbols = symbols | ranges::views::transform([source](const auto &sw) {
return IndexedEventSubscriptionSymbol{sw, source};
}) |
ranges::to<std::unordered_set<SymbolWrapper>>;
}

if (args.tape.has_value()) {
std::string tape = args.tape.value();

auto pub = DXEndpoint::newBuilder()
->withRole(DXEndpoint::Role::STREAM_PUBLISHER)
->withProperty(DXEndpoint::DXFEED_WILDCARD_ENABLE_PROPERTY, "true") // Enabled by default
->withName(getName() + "Tool")
->build()
->connect(tape.starts_with("tape:") ? tape : "tape:" + tape)
->getPublisher();

sub->addEventListener([pub](auto &&events) {
pub->publishEvents(events);
});
}

sub->addSymbols(symbols);
endpoint->connect(args.address);
std::this_thread::sleep_for(std::chrono::days(365));
}
};

Expand Down
2 changes: 1 addition & 1 deletion tools/Tools/src/PerfTest/PerfTestTool.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Connects to the specified address(es) and calculates performance counters (event
->withRole(args.isForceStream() ? DXEndpoint::Role::STREAM_FEED : DXEndpoint::Role::FEED)
->withProperty(DXEndpoint::DXFEED_WILDCARD_ENABLE_PROPERTY, "true")
->withProperties(CmdArgsUtils::parseProperties(args.getProperties()))
->withName("PerfTestTool")
->withName(getName() + "Tool")
->build();

auto sub = endpoint->getFeed()->createSubscription(CmdArgsUtils::parseTypes(args.getTypes()));
Expand Down
Loading

0 comments on commit 79642d7

Please sign in to comment.