From 2e904801a08cdd5aa7689570a1319ccd0185d21b Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Tue, 12 May 2020 19:08:16 -0700 Subject: [PATCH] (ixbots) add new class to configure a bot to simplify passing options around --- docker/Dockerfile.alpine | 2 +- docs/CHANGELOG.md | 4 ++ ixbots/CMakeLists.txt | 1 + ixbots/ixbots/IXCobraBot.cpp | 16 +++--- ixbots/ixbots/IXCobraBot.h | 11 +---- ixbots/ixbots/IXCobraBotConfig.h | 24 +++++++++ ixbots/ixbots/IXCobraToSentryBot.cpp | 18 ++----- ixbots/ixbots/IXCobraToSentryBot.h | 12 ++--- ixbots/ixbots/IXCobraToStatsdBot.cpp | 22 ++------- ixbots/ixbots/IXCobraToStatsdBot.h | 12 ++--- ixbots/ixbots/IXCobraToStdoutBot.cpp | 18 ++----- ixbots/ixbots/IXCobraToStdoutBot.h | 12 ++--- ixwebsocket/IXWebSocketVersion.h | 2 +- makefile | 2 +- test/IXCobraToSentryBotTest.cpp | 22 +++------ test/IXCobraToStatsdBotTest.cpp | 24 +++------ test/IXCobraToStdoutBotTest.cpp | 22 +++------ ws/ws.cpp | 73 ++++++++++------------------ 18 files changed, 109 insertions(+), 188 deletions(-) create mode 100644 ixbots/ixbots/IXCobraBotConfig.h diff --git a/docker/Dockerfile.alpine b/docker/Dockerfile.alpine index 8e8eb7ad..9515ab7a 100644 --- a/docker/Dockerfile.alpine +++ b/docker/Dockerfile.alpine @@ -2,7 +2,7 @@ FROM alpine:3.11 as build RUN apk add --no-cache \ gcc g++ musl-dev linux-headers \ - cmake mbedtls-dev make zlib-dev + cmake mbedtls-dev make zlib-dev ninja RUN addgroup -S app && \ adduser -S -G app app && \ diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f6e17d67..5b634b75 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All changes to this project will be documented in this file. +## [9.5.9] - 2020-05-12 + +(ixbots) add new class to configure a bot to simplify passing options around + ## [9.5.8] - 2020-05-08 (openssl tls) (openssl < 1.1) logic inversion - crypto locking callback are not registered properly diff --git a/ixbots/CMakeLists.txt b/ixbots/CMakeLists.txt index 300f8287..2e5c1d3f 100644 --- a/ixbots/CMakeLists.txt +++ b/ixbots/CMakeLists.txt @@ -13,6 +13,7 @@ set (IXBOTS_SOURCES set (IXBOTS_HEADERS ixbots/IXCobraBot.h + ixbots/IXCobraBotConfig.h ixbots/IXCobraToSentryBot.h ixbots/IXCobraToStatsdBot.h ixbots/IXCobraToStdoutBot.h diff --git a/ixbots/ixbots/IXCobraBot.cpp b/ixbots/ixbots/IXCobraBot.cpp index 609026fd..4992f20e 100644 --- a/ixbots/ixbots/IXCobraBot.cpp +++ b/ixbots/ixbots/IXCobraBot.cpp @@ -17,14 +17,16 @@ namespace ix { - int64_t CobraBot::run(const CobraConfig& config, - const std::string& channel, - const std::string& filter, - const std::string& position, - bool enableHeartbeat, - int heartBeatTimeout, - int runtime) + int64_t CobraBot::run(const CobraBotConfig& botConfig) { + auto config = botConfig.cobraConfig; + auto channel = botConfig.channel; + auto filter = botConfig.filter; + auto position = botConfig.position; + auto enableHeartbeat = botConfig.enableHeartbeat; + auto heartBeatTimeout = botConfig.heartBeatTimeout; + auto runtime = botConfig.runtime; + ix::CobraConnection conn; conn.configure(config); conn.connect(); diff --git a/ixbots/ixbots/IXCobraBot.h b/ixbots/ixbots/IXCobraBot.h index 79960a46..e8c8b4f9 100644 --- a/ixbots/ixbots/IXCobraBot.h +++ b/ixbots/ixbots/IXCobraBot.h @@ -8,7 +8,7 @@ #include #include -#include +#include "IXCobraBotConfig.h" #include #include @@ -25,14 +25,7 @@ namespace ix public: CobraBot() = default; - int64_t run(const CobraConfig& config, - const std::string& channel, - const std::string& filter, - const std::string& position, - bool enableHeartbeat, - int heartBeatTimeout, - int runtime); - + int64_t run(const CobraBotConfig& botConfig); void setOnBotMessageCallback(const OnBotMessageCallback& callback); private: diff --git a/ixbots/ixbots/IXCobraBotConfig.h b/ixbots/ixbots/IXCobraBotConfig.h new file mode 100644 index 00000000..e8edb8e0 --- /dev/null +++ b/ixbots/ixbots/IXCobraBotConfig.h @@ -0,0 +1,24 @@ +/* + * IXCobraBotConfig.h + * Author: Benjamin Sergeant + * Copyright (c) 2020 Machine Zone, Inc. All rights reserved. + */ + +#pragma once + +#include +#include + +namespace ix +{ + struct CobraBotConfig + { + CobraConfig cobraConfig; + std::string channel; + std::string filter; + std::string position = std::string("$"); + bool enableHeartbeat = true; + int heartBeatTimeout = 60; + int runtime = -1; + }; +} // namespace ix diff --git a/ixbots/ixbots/IXCobraToSentryBot.cpp b/ixbots/ixbots/IXCobraToSentryBot.cpp index ed5a770c..906f612d 100644 --- a/ixbots/ixbots/IXCobraToSentryBot.cpp +++ b/ixbots/ixbots/IXCobraToSentryBot.cpp @@ -16,15 +16,9 @@ namespace ix { - int64_t cobra_to_sentry_bot(const CobraConfig& config, - const std::string& channel, - const std::string& filter, - const std::string& position, + int64_t cobra_to_sentry_bot(const CobraBotConfig& config, SentryClient& sentryClient, - bool verbose, - bool enableHeartbeat, - int heartBeatTimeout, - int runtime) + bool verbose) { CobraBot bot; bot.setOnBotMessageCallback([&sentryClient, &verbose](const Json::Value& msg, @@ -77,12 +71,6 @@ namespace ix }); }); - return bot.run(config, - channel, - filter, - position, - enableHeartbeat, - heartBeatTimeout, - runtime); + return bot.run(config); } } // namespace ix diff --git a/ixbots/ixbots/IXCobraToSentryBot.h b/ixbots/ixbots/IXCobraToSentryBot.h index 4093d32c..7d9178b9 100644 --- a/ixbots/ixbots/IXCobraToSentryBot.h +++ b/ixbots/ixbots/IXCobraToSentryBot.h @@ -6,19 +6,13 @@ #pragma once #include -#include +#include "IXCobraBotConfig.h" #include #include namespace ix { - int64_t cobra_to_sentry_bot(const CobraConfig& config, - const std::string& channel, - const std::string& filter, - const std::string& position, + int64_t cobra_to_sentry_bot(const CobraBotConfig& config, SentryClient& sentryClient, - bool verbose, - bool enableHeartbeat, - int heartBeatTimeout, - int runtime); + bool verbose); } // namespace ix diff --git a/ixbots/ixbots/IXCobraToStatsdBot.cpp b/ixbots/ixbots/IXCobraToStatsdBot.cpp index 50422fc9..138f2566 100644 --- a/ixbots/ixbots/IXCobraToStatsdBot.cpp +++ b/ixbots/ixbots/IXCobraToStatsdBot.cpp @@ -53,23 +53,13 @@ namespace ix return val; } - int64_t cobra_to_statsd_bot(const ix::CobraConfig& config, - const std::string& channel, - const std::string& filter, - const std::string& position, + int64_t cobra_to_statsd_bot(const ix::CobraBotConfig& config, StatsdClient& statsdClient, const std::string& fields, const std::string& gauge, const std::string& timer, - bool verbose, - bool enableHeartbeat, - int heartBeatTimeout, - int runtime) + bool verbose) { - ix::CobraConnection conn; - conn.configure(config); - conn.connect(); - auto tokens = parseFields(fields); CobraBot bot; @@ -142,12 +132,6 @@ namespace ix sentCount++; }); - return bot.run(config, - channel, - filter, - position, - enableHeartbeat, - heartBeatTimeout, - runtime); + return bot.run(config); } } // namespace ix diff --git a/ixbots/ixbots/IXCobraToStatsdBot.h b/ixbots/ixbots/IXCobraToStatsdBot.h index e23e35bc..50025957 100644 --- a/ixbots/ixbots/IXCobraToStatsdBot.h +++ b/ixbots/ixbots/IXCobraToStatsdBot.h @@ -7,22 +7,16 @@ #include #include -#include +#include "IXCobraBotConfig.h" #include #include namespace ix { - int64_t cobra_to_statsd_bot(const ix::CobraConfig& config, - const std::string& channel, - const std::string& filter, - const std::string& position, + int64_t cobra_to_statsd_bot(const ix::CobraBotConfig& config, StatsdClient& statsdClient, const std::string& fields, const std::string& gauge, const std::string& timer, - bool verbose, - bool enableHeartbeat, - int heartBeatTimeout, - int runtime); + bool verbose); } // namespace ix diff --git a/ixbots/ixbots/IXCobraToStdoutBot.cpp b/ixbots/ixbots/IXCobraToStdoutBot.cpp index ef91953c..df266f7b 100644 --- a/ixbots/ixbots/IXCobraToStdoutBot.cpp +++ b/ixbots/ixbots/IXCobraToStdoutBot.cpp @@ -63,15 +63,9 @@ namespace ix } } - int64_t cobra_to_stdout_bot(const CobraConfig& config, - const std::string& channel, - const std::string& filter, - const std::string& position, + int64_t cobra_to_stdout_bot(const ix::CobraBotConfig& config, bool fluentd, - bool quiet, - bool enableHeartbeat, - int heartBeatTimeout, - int runtime) + bool quiet) { CobraBot bot; auto jsonWriter = makeStreamWriter(); @@ -89,12 +83,6 @@ namespace ix sentCount++; }); - return bot.run(config, - channel, - filter, - position, - enableHeartbeat, - heartBeatTimeout, - runtime); + return bot.run(config); } } // namespace ix diff --git a/ixbots/ixbots/IXCobraToStdoutBot.h b/ixbots/ixbots/IXCobraToStdoutBot.h index f82af481..a99d83b0 100644 --- a/ixbots/ixbots/IXCobraToStdoutBot.h +++ b/ixbots/ixbots/IXCobraToStdoutBot.h @@ -6,19 +6,13 @@ #pragma once #include -#include +#include "IXCobraBotConfig.h" #include #include namespace ix { - int64_t cobra_to_stdout_bot(const ix::CobraConfig& config, - const std::string& channel, - const std::string& filter, - const std::string& position, + int64_t cobra_to_stdout_bot(const ix::CobraBotConfig& config, bool fluentd, - bool quiet, - bool enableHeartbeat, - int heartBeatTimeout, - int runtime); + bool quiet); } // namespace ix diff --git a/ixwebsocket/IXWebSocketVersion.h b/ixwebsocket/IXWebSocketVersion.h index dc2d0282..b289105a 100644 --- a/ixwebsocket/IXWebSocketVersion.h +++ b/ixwebsocket/IXWebSocketVersion.h @@ -6,4 +6,4 @@ #pragma once -#define IX_WEBSOCKET_VERSION "9.5.8" +#define IX_WEBSOCKET_VERSION "9.5.9" diff --git a/makefile b/makefile index f9fc65ca..7a5e23dc 100644 --- a/makefile +++ b/makefile @@ -26,7 +26,7 @@ brew: # server side ?) and I can't work-around it easily, so we're using mbedtls on # Linux for the SSL backend, which works great. ws_mbedtls_install: - mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; make -j 4 install) + mkdir -p build && (cd build ; cmake -GNinja -DCMAKE_BUILD_TYPE=MinSizeRel -DUSE_TLS=1 -DUSE_WS=1 -DUSE_MBED_TLS=1 .. ; ninja install) ws: mkdir -p build && (cd build ; cmake -DCMAKE_BUILD_TYPE=Debug -DUSE_TLS=1 -DUSE_WS=1 .. ; make -j 4) diff --git a/test/IXCobraToSentryBotTest.cpp b/test/IXCobraToSentryBotTest.cpp index 4b923478..b5775efa 100644 --- a/test/IXCobraToSentryBotTest.cpp +++ b/test/IXCobraToSentryBotTest.cpp @@ -138,11 +138,12 @@ TEST_CASE("Cobra_to_sentry_bot", "[cobra_bots]") std::thread publisherThread(runPublisher, config, channel); - std::string filter; - std::string position("$"); + ix::CobraBotConfig cobraBotConfig; + cobraBotConfig.cobraConfig = config; + cobraBotConfig.channel = channel; + cobraBotConfig.runtime = 3; // Only run the bot for 3 seconds + cobraBotConfig.enableHeartbeat = false; bool verbose = true; - bool enableHeartbeat = false; - int heartBeatTimeout = 60; // FIXME: try to get this working with https instead of http // to regress the TLS 1.3 OpenSSL bug @@ -157,18 +158,9 @@ TEST_CASE("Cobra_to_sentry_bot", "[cobra_bots]") SentryClient sentryClient(dsn); sentryClient.setTLSOptions(tlsOptionsClient); - // Only run the bot for 3 seconds - int runtime = 3; - - int64_t sentCount = cobra_to_sentry_bot(config, - channel, - filter, - position, + int64_t sentCount = cobra_to_sentry_bot(cobraBotConfig, sentryClient, - verbose, - enableHeartbeat, - heartBeatTimeout, - runtime); + verbose); // // We want at least 2 messages to be sent // diff --git a/test/IXCobraToStatsdBotTest.cpp b/test/IXCobraToStatsdBotTest.cpp index 2eeef1de..e6470dc8 100644 --- a/test/IXCobraToStatsdBotTest.cpp +++ b/test/IXCobraToStatsdBotTest.cpp @@ -87,14 +87,11 @@ TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]") std::thread publisherThread(runPublisher, config, channel); - std::string filter; - std::string position("$"); - bool verbose = true; - bool enableHeartbeat = false; - int heartBeatTimeout = 60; - - // Only run the bot for 3 seconds - int runtime = 3; + ix::CobraBotConfig cobraBotConfig; + cobraBotConfig.cobraConfig = config; + cobraBotConfig.channel = channel; + cobraBotConfig.runtime = 3; // Only run the bot for 3 seconds + cobraBotConfig.enableHeartbeat = false; std::string hostname("127.0.0.1"); // std::string hostname("www.google.com"); @@ -113,19 +110,14 @@ TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]") std::string fields("device.game\ndevice.os_name"); std::string gauge; std::string timer; + bool verbose = true; - int64_t sentCount = ix::cobra_to_statsd_bot(config, - channel, - filter, - position, + int64_t sentCount = ix::cobra_to_statsd_bot(cobraBotConfig, statsdClient, fields, gauge, timer, - verbose, - enableHeartbeat, - heartBeatTimeout, - runtime); + verbose); // // We want at least 2 messages to be sent // diff --git a/test/IXCobraToStdoutBotTest.cpp b/test/IXCobraToStdoutBotTest.cpp index 0ff34809..79c07b62 100644 --- a/test/IXCobraToStdoutBotTest.cpp +++ b/test/IXCobraToStdoutBotTest.cpp @@ -85,27 +85,19 @@ TEST_CASE("Cobra_to_stdout_bot", "[cobra_bots]") std::thread publisherThread(runPublisher, config, channel); - std::string filter; - std::string position("$"); + ix::CobraBotConfig cobraBotConfig; + cobraBotConfig.cobraConfig = config; + cobraBotConfig.channel = channel; + cobraBotConfig.runtime = 3; // Only run the bot for 3 seconds + cobraBotConfig.enableHeartbeat = false; bool quiet = false; - bool enableHeartbeat = false; - int heartBeatTimeout = 60; - - // Only run the bot for 3 seconds - int runtime = 3; // We could try to capture the output ... not sure how. bool fluentd = true; - int64_t sentCount = ix::cobra_to_stdout_bot(config, - channel, - filter, - position, + int64_t sentCount = ix::cobra_to_stdout_bot(cobraBotConfig, fluentd, - quiet, - enableHeartbeat, - heartBeatTimeout, - runtime); + quiet); // // We want at least 2 messages to be sent // diff --git a/ws/ws.cpp b/ws/ws.cpp index d15189e9..7ffd0650 100644 --- a/ws/ws.cpp +++ b/ws/ws.cpp @@ -120,6 +120,7 @@ int main(int argc, char** argv) std::string logfile; ix::SocketTLSOptions tlsOptions; ix::CobraConfig cobraConfig; + ix::CobraBotConfig cobraBotConfig; std::string ciphers; std::string redirectUrl; bool headersOnly = false; @@ -149,8 +150,6 @@ int main(int argc, char** argv) int count = 1; uint32_t maxWaitBetweenReconnectionRetries; int pingIntervalSecs = 30; - int runtime = -1; // run indefinitely - int heartBeatTimeout = 60; auto addTLSOptions = [&tlsOptions, &verifyNone](CLI::App* app) { app->add_option( @@ -174,6 +173,19 @@ int main(int argc, char** argv) app->add_option("--rolesecret", cobraConfig.rolesecret, "Role secret")->required(); }; + auto addCobraBotConfig = [&cobraBotConfig](CLI::App* app) { + app->add_option("--appkey", cobraBotConfig.cobraConfig.appkey, "Appkey")->required(); + app->add_option("--endpoint", cobraBotConfig.cobraConfig.endpoint, "Endpoint")->required(); + app->add_option("--rolename", cobraBotConfig.cobraConfig.rolename, "Role name")->required(); + app->add_option("--rolesecret", cobraBotConfig.cobraConfig.rolesecret, "Role secret")->required(); + app->add_option("--channel", cobraBotConfig.channel, "Channel")->required(); + app->add_option("--filter", cobraBotConfig.filter, "Filter"); + app->add_option("--position", cobraBotConfig.position, "Position"); + app->add_option("--runtime", cobraBotConfig.runtime, "Runtime"); + app->add_option("--heartbeat", cobraBotConfig.enableHeartbeat, "Runtime"); + app->add_option("--heartbeat_timeout", cobraBotConfig.heartBeatTimeout, "Runtime"); + }; + app.add_flag("--version", version, "Print ws version"); app.add_option("--logfile", logfile, "path where all logs will be redirected"); @@ -281,16 +293,11 @@ int main(int argc, char** argv) CLI::App* cobraSubscribeApp = app.add_subcommand("cobra_subscribe", "Cobra subscriber"); cobraSubscribeApp->fallthrough(); - cobraSubscribeApp->add_option("--channel", channel, "Channel")->required(); cobraSubscribeApp->add_option("--pidfile", pidfile, "Pid file"); - cobraSubscribeApp->add_option("--filter", filter, "Stream SQL Filter"); - cobraSubscribeApp->add_option("--position", position, "Stream position"); cobraSubscribeApp->add_flag("-q", quiet, "Quiet / only display stats"); cobraSubscribeApp->add_flag("--fluentd", fluentd, "Write fluentd prefix"); - cobraSubscribeApp->add_option("--runtime", runtime, "Runtime in seconds"); - cobraSubscribeApp->add_option("--heartbeat_timeout", heartBeatTimeout, "Heartbeat timeout"); addTLSOptions(cobraSubscribeApp); - addCobraConfig(cobraSubscribeApp); + addCobraBotConfig(cobraSubscribeApp); CLI::App* cobraPublish = app.add_subcommand("cobra_publish", "Cobra publisher"); cobraPublish->fallthrough(); @@ -324,28 +331,18 @@ int main(int argc, char** argv) ->join(); cobra2statsd->add_option("--timer", timer, "Value to extract, and use as a statsd timer") ->join(); - cobra2statsd->add_option("channel", channel, "Channel")->required(); cobra2statsd->add_flag("-v", verbose, "Verbose"); cobra2statsd->add_option("--pidfile", pidfile, "Pid file"); - cobra2statsd->add_option("--filter", filter, "Stream SQL Filter"); - cobra2statsd->add_option("--position", position, "Stream position"); - cobra2statsd->add_option("--runtime", runtime, "Runtime in seconds"); - cobra2statsd->add_option("--heartbeat_timeout", heartBeatTimeout, "Heartbeat timeout"); addTLSOptions(cobra2statsd); - addCobraConfig(cobra2statsd); + addCobraBotConfig(cobra2statsd); CLI::App* cobra2sentry = app.add_subcommand("cobra_to_sentry", "Cobra metrics to sentry"); cobra2sentry->fallthrough(); cobra2sentry->add_option("--dsn", dsn, "Sentry DSN"); - cobra2sentry->add_option("channel", channel, "Channel")->required(); cobra2sentry->add_flag("-v", verbose, "Verbose"); cobra2sentry->add_option("--pidfile", pidfile, "Pid file"); - cobra2sentry->add_option("--filter", filter, "Stream SQL Filter"); - cobra2sentry->add_option("--position", position, "Stream position"); - cobra2sentry->add_option("--runtime", runtime, "Runtime in seconds"); - cobra2sentry->add_option("--heartbeat_timeout", heartBeatTimeout, "Heartbeat timeout"); addTLSOptions(cobra2sentry); - addCobraConfig(cobra2sentry); + addCobraBotConfig(cobra2sentry); CLI::App* cobra2redisApp = app.add_subcommand("cobra_metrics_to_redis", "Cobra metrics to redis"); @@ -456,6 +453,9 @@ int main(int argc, char** argv) cobraConfig.webSocketPerMessageDeflateOptions = ix::WebSocketPerMessageDeflateOptions(true); cobraConfig.socketTLSOptions = tlsOptions; + cobraBotConfig.cobraConfig.webSocketPerMessageDeflateOptions = ix::WebSocketPerMessageDeflateOptions(true); + cobraBotConfig.cobraConfig.socketTLSOptions = tlsOptions; + int ret = 1; if (app.got_subcommand("transfer")) { @@ -525,16 +525,9 @@ int main(int argc, char** argv) } else if (app.got_subcommand("cobra_subscribe")) { - bool enableHeartbeat = true; - int64_t sentCount = ix::cobra_to_stdout_bot(cobraConfig, - channel, - filter, - position, + int64_t sentCount = ix::cobra_to_stdout_bot(cobraBotConfig, fluentd, - quiet, - enableHeartbeat, - heartBeatTimeout, - runtime); + quiet); ret = (int) sentCount; } else if (app.got_subcommand("cobra_publish")) @@ -555,7 +548,6 @@ int main(int argc, char** argv) } else { - bool enableHeartbeat = true; ix::StatsdClient statsdClient(hostname, statsdPort, prefix); std::string errMsg; @@ -567,36 +559,23 @@ int main(int argc, char** argv) } else { - ret = (int) ix::cobra_to_statsd_bot(cobraConfig, - channel, - filter, - position, + ret = (int) ix::cobra_to_statsd_bot(cobraBotConfig, statsdClient, fields, gauge, timer, - verbose, - enableHeartbeat, - heartBeatTimeout, - runtime); + verbose); } } } else if (app.got_subcommand("cobra_to_sentry")) { - bool enableHeartbeat = true; ix::SentryClient sentryClient(dsn); sentryClient.setTLSOptions(tlsOptions); - ret = (int) ix::cobra_to_sentry_bot(cobraConfig, - channel, - filter, - position, + ret = (int) ix::cobra_to_sentry_bot(cobraBotConfig, sentryClient, - verbose, - enableHeartbeat, - heartBeatTimeout, - runtime); + verbose); } else if (app.got_subcommand("cobra_metrics_to_redis")) {