diff options
Diffstat (limited to 'config/src/apps/vespa-get-config/getconfig.cpp')
-rw-r--r-- | config/src/apps/vespa-get-config/getconfig.cpp | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/config/src/apps/vespa-get-config/getconfig.cpp b/config/src/apps/vespa-get-config/getconfig.cpp new file mode 100644 index 00000000000..795916241b2 --- /dev/null +++ b/config/src/apps/vespa-get-config/getconfig.cpp @@ -0,0 +1,264 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. + +#include <vespa/fnet/frt/frt.h> +#include <vespa/config/config.h> +#include <vespa/config/frt/frtconfigrequestfactory.h> +#include <vespa/config/frt/frtconnection.h> +#include <vespa/config/common/payload_converter.h> +#include <vespa/fastos/app.h> + + +#include <string> +#include <sstream> +#include <fstream> + +#include <vespa/log/log.h> +LOG_SETUP("vespa-get-config"); + +using namespace config; + +class GetConfig : public FastOS_Application +{ +private: + FRT_Supervisor *_supervisor; + FRT_Target *_target; + + GetConfig(const GetConfig &); + GetConfig &operator=(const GetConfig &); + +public: + GetConfig() : _supervisor(NULL), _target(NULL) {} + virtual ~GetConfig(); + int usage(); + void initRPC(const char *spec); + void finiRPC(); + int Main() override; +}; + + +GetConfig::~GetConfig() +{ + LOG_ASSERT(_supervisor == NULL); + LOG_ASSERT(_target == NULL); +} + + +int +GetConfig::usage() +{ + fprintf(stderr, "usage: %s -n name -i configId\n", _argv[0]); + fprintf(stderr, "-n name (config name, including namespace, on the form <namespace>.<name>)\n"); + fprintf(stderr, "-i configId (config id, optional)\n"); + fprintf(stderr, "-j (output config as json)\n"); + fprintf(stderr, "-a schema (config def schema file, optional)\n"); + fprintf(stderr, "-v defVersion (config definition version, optional, deprecated)\n"); + fprintf(stderr, "-m defMd5 (definition md5sum, optional)\n"); + fprintf(stderr, "-c configMd5 (config md5sum, optional)\n"); + fprintf(stderr, "-t serverTimeout (server timeout in seconds, default 3)\n"); + fprintf(stderr, "-w timeout (timeout in seconds, default 10)\n"); + fprintf(stderr, "-s server (server hostname, default localhost)\n"); + fprintf(stderr, "-p port (proxy/server port number, default 19090)\n"); + fprintf(stderr, "-r traceLevel (tracelevel to use in request, default 0\n"); + fprintf(stderr, "-V vespaVersion (vespa version to use in request, optional\n"); + fprintf(stderr, "-d (debug mode)\n"); + fprintf(stderr, "-h (This help text)\n"); + return 1; +} + + +void +GetConfig::initRPC(const char *spec) +{ + _supervisor = new FRT_Supervisor(); + _target = _supervisor->GetTarget(spec); + _supervisor->Start(); +} + + +void +GetConfig::finiRPC() +{ + if (_target != NULL) { + _target->SubRef(); + _target = NULL; + } + if (_supervisor != NULL) { + _supervisor->ShutDown(true); + delete _supervisor; + _supervisor = NULL; + } +} + + +int +GetConfig::Main() +{ + bool debugging = false; + char c = -1; + + std::vector<vespalib::string> defSchema; + const char *schema = NULL; + const char *defName = NULL; + const char *defMD5 = ""; + std::string defNamespace("config"); + const char *serverHost = "localhost"; + const char *configId = getenv("VESPA_CONFIG_ID"); + bool printAsJson = false; + int traceLevel = config::protocol::readTraceLevel(); + const char *vespaVersionString = nullptr; + + if (configId == NULL) { + configId = ""; + } + const char *configMD5 = ""; + int serverTimeout = 3; + int clientTimeout = 10; + + int serverPort = 19090; + + const char *optArg = NULL; + int optInd = 0; + while ((c = GetOpt("a:n:v:i:jm:c:t:V:w:r:s:p:dh", optArg, optInd)) != -1) { + int retval = 1; + switch (c) { + case 'a': + schema = optArg; + break; + case 'n': + defName = optArg; + break; + case 'v': + break; + case 'i': + configId = optArg; + break; + case 'j': + printAsJson = true; + break; + case 'm': + defMD5 = optArg; + break; + case 'c': + configMD5 = optArg; + break; + case 't': + serverTimeout = atoi(optArg); + break; + case 'w': + clientTimeout = atoi(optArg); + break; + case 'r': + traceLevel = atoi(optArg); + break; + case 'V': + vespaVersionString = optArg; + break; + case 's': + serverHost = optArg; + break; + case 'p': + serverPort = atoi(optArg); + break; + case 'd': + debugging = true; + break; + case 'h': + retval = 0; + case '?': + default: + usage(); + return retval; + } + } + + if (defName == NULL || serverPort == 0) { + usage(); + return 1; + } + + if (strchr(defName, '.') != NULL) { + const char *tmp = defName; + defName = strrchr(defName, '.'); + defName++; + defNamespace = std::string(tmp, defName - tmp - 1); + } + + if (schema != NULL) { + std::ifstream is; + is.open(schema); + std::string item; + while (std::getline(is, item)) { + if (item.find("namespace=") == std::string::npos) { + defSchema.push_back(item); + } + } + is.close(); + } + std::ostringstream tmp; + tmp << "tcp/"; + tmp << serverHost; + tmp << ":"; + tmp << serverPort; + std::string sspec = tmp.str(); + const char *spec = sspec.c_str(); + if (debugging) { + printf("connecting to '%s'\n", spec); + } + initRPC(spec); + + auto vespaVersion = VespaVersion::getCurrentVersion(); + if (vespaVersionString != nullptr) { + vespaVersion = VespaVersion::fromString(vespaVersionString); + } + + int protocolVersion = config::protocol::readProtocolVersion(); + FRTConfigRequestFactory requestFactory(protocolVersion, traceLevel, vespaVersion, config::protocol::readProtocolCompressionType()); + FRTConnection connection(spec, *_supervisor, TimingValues()); + ConfigKey key(configId, defName, defNamespace, defMD5, defSchema); + ConfigState state(configMD5, 0); + FRTConfigRequest::UP request = requestFactory.createConfigRequest(key, &connection, state, serverTimeout * 1000); + + _target->InvokeSync(request->getRequest(), clientTimeout); // seconds + + ConfigResponse::UP response = request->createResponse(request->getRequest()); + response->validateResponse(); + if (response->isError()) { + fprintf(stderr, "error %d: %s\n", + response->errorCode(), response->errorMessage().c_str()); + } else { + response->fill(); + ConfigKey rKey(response->getKey()); + ConfigState rState(response->getConfigState()); + ConfigValue rValue(response->getValue()); + if (debugging) { + printf("defName %s\n", rKey.getDefName().c_str()); + printf("defMD5 %s\n", rKey.getDefMd5().c_str()); + printf("defNamespace %s\n", rKey.getDefNamespace().c_str()); + + printf("configID %s\n", rKey.getConfigId().c_str()); + printf("configMD5 %s\n", rState.md5.c_str()); + + printf("generation %" PRId64 "\n", rState.generation); + printf("trace %s\n", response->getTrace().toString().c_str()); + } else if (traceLevel > 0) { + printf("trace %s\n", response->getTrace().toString().c_str()); + } + // TODO: Make printAsJson default + if (printAsJson) { + printf("%s\n", rValue.asJson().c_str()); + } else { + std::vector<vespalib::string> lines = rValue.getLegacyFormat(); + for (uint32_t j = 0; j < lines.size(); j++) { + printf("%s\n", lines[j].c_str()); + } + } + } + finiRPC(); + return 0; +} + +int main(int argc, char **argv) +{ + GetConfig app; + return app.Entry(argc, argv); +} |