Status LoggerPlugin::call(const PluginRequest& request, PluginResponse& response) { QueryLogItem item; std::vector<StatusLogLine> intermediate_logs; if (request.count("string") > 0) { return this->logString(request.at("string")); } else if (request.count("snapshot") > 0) { return this->logSnapshot(request.at("snapshot")); } else if (request.count("init") > 0) { deserializeIntermediateLog(request, intermediate_logs); this->init(request.at("init"), intermediate_logs); return Status(0); } else if (request.count("status") > 0) { deserializeIntermediateLog(request, intermediate_logs); return this->logStatus(intermediate_logs); } else if (request.count("event") > 0) { return this->logEvent(request.at("event")); } else if (request.count("action") && request.at("action") == "features") { size_t features = 0; features |= (usesLogStatus()) ? LOGGER_FEATURE_LOGSTATUS : 0; features |= (usesLogEvent()) ? LOGGER_FEATURE_LOGEVENT : 0; return Status(features); } else { return Status(1, "Unsupported call to logger plugin"); } }
Status TablePlugin::call(const PluginRequest& request, PluginResponse& response) { response.clear(); // TablePlugin API calling requires an action. if (request.count("action") == 0) { return Status(1, "Table plugins must include a request action"); } if (request.at("action") == "generate") { // "generate" runs the table implementation using a PluginRequest with // optional serialized QueryContext and returns the QueryData results as // the PluginRequest data. QueryContext context; if (request.count("context") > 0) { setContextFromRequest(request, context); } response = generate(context); } else if (request.at("action") == "columns") { // "columns" returns a PluginRequest filled with column information // such as name and type. const auto& column_list = columns(); for (const auto& column : column_list) { response.push_back( {{"name", column.first}, {"type", columnTypeName(column.second)}}); } } else if (request.at("action") == "definition") { response.push_back({{"definition", columnDefinition()}}); } else { return Status(1, "Unknown table plugin action: " + request.at("action")); } return Status(0, "OK"); }
Status ConfigPlugin::call(const PluginRequest& request, PluginResponse& response) { if (request.count("action") == 0) { return Status(1, "Config plugins require an action in PluginRequest"); } if (request.at("action") == "genConfig") { std::map<std::string, std::string> config; auto stat = genConfig(config); response.push_back(config); return stat; } else if (request.at("action") == "genPack") { if (request.count("name") == 0 || request.count("value") == 0) { return Status(1, "Missing name or value"); } std::string pack; auto stat = genPack(request.at("name"), request.at("value"), pack); response.push_back({{request.at("name"), pack}}); return stat; } else if (request.at("action") == "update") { if (request.count("source") == 0 || request.count("data") == 0) { return Status(1, "Missing source or data"); } return Config::getInstance().update( {{request.at("source"), request.at("data")}}); } return Status(1, "Config plugin action unknown: " + request.at("action")); }
static void deserializeIntermediateLog(const PluginRequest& request, std::vector<StatusLogLine>& log) { if (request.count("log") == 0) { return; } // Read the plugin request string into a JSON tree and enumerate. pt::ptree tree; try { std::stringstream input; input << request.at("log"); pt::read_json(input, tree); } catch (const pt::json_parser::json_parser_error& e) { return; } for (const auto& item : tree.get_child("")) { log.push_back({ (StatusLogSeverity)item.second.get<int>("s", O_INFO), item.second.get<std::string>("f", "<unknown>"), item.second.get<int>("i", 0), item.second.get<std::string>("m", ""), }); } }
Status DatabasePlugin::call(const PluginRequest& request, PluginResponse& response) { if (request.count("action") == 0) { return Status(1, "Database plugin must include a request action"); } // Get a domain/key, which are used for most database plugin actions. auto domain = (request.count("domain") > 0) ? request.at("domain") : ""; auto key = (request.count("key") > 0) ? request.at("key") : ""; // Switch over the possible database plugin actions. if (request.at("action") == "get") { std::string value; auto status = this->get(domain, key, value); response.push_back({{"v", value}}); return status; } else if (request.at("action") == "put") { if (request.count("value") == 0) { return Status(1, "Database plugin put action requires a value"); } return this->put(domain, key, request.at("value")); } else if (request.at("action") == "remove") { return this->remove(domain, key); } else if (request.at("action") == "scan") { std::vector<std::string> keys; auto status = this->scan(domain, keys); for (const auto& key : keys) { response.push_back({{"k", key}}); } return status; } return Status(1, "Unknown database plugin action"); }
Status LoggerPlugin::call(const PluginRequest& request, PluginResponse& response) { QueryLogItem item; std::vector<StatusLogLine> intermediate_logs; if (request.count("string") > 0) { return this->logString(request.at("string")); } else if (request.count("snapshot") > 0) { return this->logSnapshot(request.at("snapshot")); } else if (request.count("init") > 0) { deserializeIntermediateLog(request, intermediate_logs); this->init(request.at("init"), intermediate_logs); return Status(this->usesLogStatus() ? 0 : 1); } else if (request.count("status") > 0) { deserializeIntermediateLog(request, intermediate_logs); return this->logStatus(intermediate_logs); } else { return Status(1, "Unsupported call to logger plugin"); } }
Status LoggerPlugin::call(const PluginRequest& request, PluginResponse& response) { QueryLogItem item; std::vector<StatusLogLine> intermediate_logs; if (request.count("string") > 0) { auto status = Status(0, "OK"); if (request.count("category") && request.at("category") == "event") { // Optionally overload the logEvent method, but receive a duplicate. // message to log string. deserializeQueryLogItemJSON(request.at("event"), item); status = this->logEvent(item); } if (status.ok()) { return this->logString(request.at("string")); } else { return status; } } else if (request.count("snapshot") > 0) { deserializeQueryLogItemJSON(request.at("snapshot"), item); return this->logSnapshot(item); } else if (request.count("health") > 0) { deserializeQueryLogItemJSON(request.at("health"), item); return this->logHealth(item); } else if (request.count("init") > 0) { deserializeIntermediateLog(request, intermediate_logs); return this->init(request.at("init"), intermediate_logs); } else if (request.count("status") > 0) { deserializeIntermediateLog(request, intermediate_logs); return this->logStatus(intermediate_logs); } else { return Status(1, "Unsupported call to logger plugin"); } }
Status DatabasePlugin::call(const PluginRequest& request, PluginResponse& response) { if (request.count("action") == 0) { return Status(1, "Database plugin must include a request action"); } // Get a domain/key, which are used for most database plugin actions. auto domain = (request.count("domain") > 0) ? request.at("domain") : ""; auto key = (request.count("key") > 0) ? request.at("key") : ""; // Switch over the possible database plugin actions. if (request.at("action") == "get") { std::string value; auto status = this->get(domain, key, value); response.push_back({{"v", value}}); return status; } else if (request.at("action") == "put") { if (request.count("value") == 0) { return Status(1, "Database plugin put action requires a value"); } return this->put(domain, key, request.at("value")); } else if (request.at("action") == "remove") { return this->remove(domain, key); } else if (request.at("action") == "scan") { // Accumulate scanned keys into a vector. std::vector<std::string> keys; // Optionally allow the caller to request a max number of keys. size_t max = 0; if (request.count("max") > 0) { max = std::stoul(request.at("max")); } auto status = this->scan(domain, keys, request.at("prefix"), max); for (const auto& k : keys) { response.push_back({{"k", k}}); } return status; } return Status(1, "Unknown database plugin action"); }
void TablePlugin::setContextFromRequest(const PluginRequest& request, QueryContext& context) { if (request.count("context") == 0) { return; } // Read serialized context from PluginRequest. std::stringstream input; input << request.at("context"); boost::property_tree::ptree tree; boost::property_tree::read_json(input, tree); // Set the context limit and deserialize each column constraint list. context.limit = tree.get<int>("limit"); for (const auto& constraint : tree.get_child("constraints")) { auto column_name = constraint.second.get<std::string>("name"); context.constraints[column_name].unserialize(constraint.second); } }
Status EnrollPlugin::call(const PluginRequest& request, PluginResponse& response) { if (FLAGS_disable_enrollment) { return Status(0, "Enrollment disabled"); } // Only support the 'enroll' action. if (request.count("action") == 0 || request.at("action") != "enroll") { return Status(1, "Enroll plugins require an action"); } // The 'enroll' API should return a string and implement caching. auto node_key = this->enroll(); response.push_back({{"node_key", node_key}}); if (node_key.size() == 0) { return Status(1, "No enrollment key found/retrieved"); } else { return Status(0, "OK"); } }
/// Plugin types should contain generic request/response formatters and /// decorators. std::string secretPower(const PluginRequest& request) const { if (request.count("secret_power") > 0U) { return request.at("secret_power"); } return "no_secret_power"; }
Status DatabasePlugin::call(const PluginRequest& request, PluginResponse& response) { if (request.count("action") == 0) { return Status(1, "Database plugin must include a request action"); } // Get a domain/key, which are used for most database plugin actions. auto domain = (request.count("domain") > 0) ? request.at("domain") : ""; auto key = (request.count("key") > 0) ? request.at("key") : ""; if (request.at("action") == "reset") { WriteLock lock(kDatabaseReset); DatabasePlugin::kDBInitialized = false; // Prevent RocksDB reentrancy by logger plugins during plugin setup. VLOG(1) << "Resetting the database plugin: " << getName(); auto status = this->reset(); if (!status.ok()) { // The active database could not be reset, fallback to an ephemeral. Registry::get().setActive("database", "ephemeral"); LOG(WARNING) << "Unable to reset database plugin: " << getName(); } DatabasePlugin::kDBInitialized = true; return status; } // Switch over the possible database plugin actions. ReadLock lock(kDatabaseReset); if (request.at("action") == "get") { std::string value; auto status = this->get(domain, key, value); response.push_back({{"v", value}}); return status; } else if (request.at("action") == "put") { if (request.count("value") == 0) { return Status(1, "Database plugin put action requires a value"); } return this->put(domain, key, request.at("value")); } else if (request.at("action") == "remove") { return this->remove(domain, key); } else if (request.at("action") == "remove_range") { auto key_high = (request.count("high") > 0) ? request.at("key_high") : ""; if (!key_high.empty() && !key.empty()) { return this->removeRange(domain, key, key_high); } return Status(1, "Missing range"); } else if (request.at("action") == "scan") { // Accumulate scanned keys into a vector. std::vector<std::string> keys; // Optionally allow the caller to request a max number of keys. size_t max = 0; if (request.count("max") > 0) { max = std::stoul(request.at("max")); } auto status = this->scan(domain, keys, request.at("prefix"), max); for (const auto& k : keys) { response.push_back({{"k", k}}); } return status; } return Status(1, "Unknown database plugin action"); }