205 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (c) 2016 MariaDB Corporation Ab
 | 
						|
 *
 | 
						|
 * Use of this software is governed by the Business Source License included
 | 
						|
 * in the LICENSE.TXT file and at www.mariadb.com/bsl11.
 | 
						|
 *
 | 
						|
 * Change Date: 2023-01-01
 | 
						|
 *
 | 
						|
 * On the date above, in accordance with the Business Source License, use
 | 
						|
 * of this software will be governed by version 2 or later of the General
 | 
						|
 * Public License.
 | 
						|
 */
 | 
						|
 | 
						|
#include "maxrest.hh"
 | 
						|
 | 
						|
using namespace std;
 | 
						|
 | 
						|
MaxRest::Server::Server(const MaxRest& maxrest, json_t* pObject)
 | 
						|
    : name       (maxrest.get<string> (pObject, "id", Presence::MANDATORY))
 | 
						|
    , address    (maxrest.get<string> (pObject, "attributes/parameters/address"))
 | 
						|
    , port       (maxrest.get<int64_t>(pObject, "attributes/parameters/port"))
 | 
						|
    , connections(maxrest.get<int64_t>(pObject, "attributes/statistics/connections"))
 | 
						|
    , state      (maxrest.get<string> (pObject, "attributes/state"))
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
MaxRest::MaxRest(TestConnections* pTest)
 | 
						|
    : m_test(*pTest)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
unique_ptr<json_t> MaxRest::v1_servers(const string& id) const
 | 
						|
{
 | 
						|
    string path("servers");
 | 
						|
    path += "/";
 | 
						|
    path += id;
 | 
						|
 | 
						|
    return curl_get(path);
 | 
						|
}
 | 
						|
 | 
						|
unique_ptr<json_t> MaxRest::v1_servers() const
 | 
						|
{
 | 
						|
    return curl_get("servers");
 | 
						|
}
 | 
						|
 | 
						|
void MaxRest::v1_maxscale_modules(const string& module,
 | 
						|
                                  const string& command,
 | 
						|
                                  const string& instance,
 | 
						|
                                  const std::vector<string>& params) const
 | 
						|
{
 | 
						|
    string path("maxscale/modules");
 | 
						|
 | 
						|
    path += "/";
 | 
						|
    path += module;
 | 
						|
    path += "/";
 | 
						|
    path += command;
 | 
						|
    path += "?";
 | 
						|
    path += instance;
 | 
						|
 | 
						|
    if (!params.empty())
 | 
						|
    {
 | 
						|
        for (const auto& param : params)
 | 
						|
        {
 | 
						|
            path += "\\&";
 | 
						|
            path += param;
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    curl_post(path);
 | 
						|
}
 | 
						|
 | 
						|
MaxRest::Server MaxRest::show_server(const std::string& id) const
 | 
						|
{
 | 
						|
    unique_ptr<json_t> sObject = v1_servers(id);
 | 
						|
    json_t* pData = get_object(sObject.get(), "data", Presence::MANDATORY);
 | 
						|
    return Server(*this, pData);
 | 
						|
}
 | 
						|
 | 
						|
vector<MaxRest::Server> MaxRest::list_servers() const
 | 
						|
{
 | 
						|
    return get_array<Server>(v1_servers().get(), "data", Presence::MANDATORY);
 | 
						|
}
 | 
						|
 | 
						|
json_t* MaxRest::get_object(json_t* pObject, const string& key, Presence presence) const
 | 
						|
{
 | 
						|
    json_t* pValue = json_object_get(pObject, key.c_str());
 | 
						|
 | 
						|
    if (!pValue && (presence == Presence::MANDATORY))
 | 
						|
    {
 | 
						|
        raise("Mandatory key '" + key + "' not present.");
 | 
						|
    }
 | 
						|
 | 
						|
    return pValue;
 | 
						|
}
 | 
						|
 | 
						|
json_t* MaxRest::get_leaf_object(json_t* pObject, const string& key, Presence presence) const
 | 
						|
{
 | 
						|
    auto i = key.find("/");
 | 
						|
 | 
						|
    if (i == string::npos)
 | 
						|
    {
 | 
						|
        pObject = get_object(pObject, key, presence);
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        string head = key.substr(0, i);
 | 
						|
        string tail = key.substr(i + 1);
 | 
						|
 | 
						|
        pObject = get_object(pObject, head, Presence::MANDATORY);
 | 
						|
        pObject = get_leaf_object(pObject, tail, presence);
 | 
						|
    }
 | 
						|
 | 
						|
    return pObject;
 | 
						|
}
 | 
						|
 | 
						|
unique_ptr<json_t> MaxRest::parse(const string& json) const
 | 
						|
{
 | 
						|
    json_error_t error;
 | 
						|
    unique_ptr<json_t> sRoot(json_loads(json.c_str(), 0, &error));
 | 
						|
 | 
						|
    if (!sRoot)
 | 
						|
    {
 | 
						|
        raise("JSON parsing failed: " + string(error.text));
 | 
						|
    }
 | 
						|
 | 
						|
    return sRoot;
 | 
						|
}
 | 
						|
 | 
						|
unique_ptr<json_t> MaxRest::curl_get(const string& path) const
 | 
						|
{
 | 
						|
    return curl(GET, path);
 | 
						|
}
 | 
						|
 | 
						|
unique_ptr<json_t> MaxRest::curl_post(const string& path) const
 | 
						|
{
 | 
						|
    return curl(POST, path);
 | 
						|
}
 | 
						|
 | 
						|
unique_ptr<json_t> MaxRest::curl(Command command, const string& path) const
 | 
						|
{
 | 
						|
    string url = "http://127.0.0.1:8989/v1/" + path;
 | 
						|
    string curl_command = "curl -u admin:mariadb ";
 | 
						|
 | 
						|
    switch (command)
 | 
						|
    {
 | 
						|
    case GET:
 | 
						|
        curl_command += "-X GET ";
 | 
						|
        break;
 | 
						|
 | 
						|
    case POST:
 | 
						|
        curl_command += "-X POST ";
 | 
						|
        break;
 | 
						|
    }
 | 
						|
 | 
						|
    curl_command += url;
 | 
						|
 | 
						|
    auto result = m_test.maxscales->ssh_output(curl_command.c_str(), 0, false);
 | 
						|
 | 
						|
    if (result.first != 0)
 | 
						|
    {
 | 
						|
        raise("Invocation of curl failed: " + to_string(result.first));
 | 
						|
    }
 | 
						|
 | 
						|
    unique_ptr<json_t> sRv;
 | 
						|
 | 
						|
    if (!result.second.empty())
 | 
						|
    {
 | 
						|
        sRv = parse(result.second);
 | 
						|
    }
 | 
						|
 | 
						|
    return sRv;
 | 
						|
}
 | 
						|
 | 
						|
void MaxRest::raise(const std::string& message) const
 | 
						|
{
 | 
						|
    ++m_test.global_result;
 | 
						|
    throw runtime_error(message);
 | 
						|
}
 | 
						|
 | 
						|
template<>
 | 
						|
string MaxRest::get<string>(json_t* pObject, const string& key, Presence presence) const
 | 
						|
{
 | 
						|
    json_t* pValue = get_leaf_object(pObject, key, presence);
 | 
						|
 | 
						|
    if (pValue && !json_is_string(pValue))
 | 
						|
    {
 | 
						|
        raise("Key '" + key + "' is present, but value is not a string.");
 | 
						|
    }
 | 
						|
 | 
						|
    return pValue ? json_string_value(pValue) : "";
 | 
						|
}
 | 
						|
 | 
						|
template<>
 | 
						|
int64_t MaxRest::get<int64_t>(json_t* pObject, const string& key, Presence presence) const
 | 
						|
{
 | 
						|
    json_t* pValue = get_leaf_object(pObject, key, presence);
 | 
						|
 | 
						|
    if (pValue && !json_is_integer(pValue))
 | 
						|
    {
 | 
						|
        raise("Key '" + key + "' is present, but value is not an integer.");
 | 
						|
    }
 | 
						|
 | 
						|
    return pValue ? json_integer_value(pValue) : 0;
 | 
						|
}
 |