386 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			386 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 * Copyright (c) 2018 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: 2024-11-16
 | 
						|
 *
 | 
						|
 * 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.
 | 
						|
 */
 | 
						|
#pragma once
 | 
						|
 | 
						|
/**
 | 
						|
 * Internal header for the server type
 | 
						|
 */
 | 
						|
 | 
						|
#include <maxbase/ccdefs.hh>
 | 
						|
 | 
						|
#include <map>
 | 
						|
#include <mutex>
 | 
						|
#include <maxscale/config.hh>
 | 
						|
#include <maxscale/server.hh>
 | 
						|
#include <maxscale/resultset.hh>
 | 
						|
 | 
						|
// Private server implementation
 | 
						|
class Server : public SERVER
 | 
						|
{
 | 
						|
public:
 | 
						|
    Server(const std::string& name,
 | 
						|
           const std::string& protocol = "",
 | 
						|
           const std::string& authenticator = "",
 | 
						|
           std::unique_ptr<mxs::SSLContext> ssl = {})
 | 
						|
        : SERVER(std::move(ssl))
 | 
						|
        , m_name(name)
 | 
						|
    {
 | 
						|
        m_settings.protocol = protocol;
 | 
						|
        m_settings.authenticator = authenticator;
 | 
						|
    }
 | 
						|
 | 
						|
    long persistpoolmax() const
 | 
						|
    {
 | 
						|
        return m_settings.persistpoolmax;
 | 
						|
    }
 | 
						|
 | 
						|
    void set_persistpoolmax(long persistpoolmax)
 | 
						|
    {
 | 
						|
        m_settings.persistpoolmax = persistpoolmax;
 | 
						|
    }
 | 
						|
 | 
						|
    long persistmaxtime() const
 | 
						|
    {
 | 
						|
        return m_settings.persistmaxtime;
 | 
						|
    }
 | 
						|
 | 
						|
    void set_persistmaxtime(long persistmaxtime)
 | 
						|
    {
 | 
						|
        m_settings.persistmaxtime = persistmaxtime;
 | 
						|
    }
 | 
						|
 | 
						|
    void set_rank(int64_t rank)
 | 
						|
    {
 | 
						|
        m_settings.rank = rank;
 | 
						|
    }
 | 
						|
 | 
						|
    bool have_disk_space_limits() const override
 | 
						|
    {
 | 
						|
        std::lock_guard<std::mutex> guard(m_settings.lock);
 | 
						|
        return !m_settings.disk_space_limits.empty();
 | 
						|
    }
 | 
						|
 | 
						|
    DiskSpaceLimits get_disk_space_limits() const override
 | 
						|
    {
 | 
						|
        std::lock_guard<std::mutex> guard(m_settings.lock);
 | 
						|
        return m_settings.disk_space_limits;
 | 
						|
    }
 | 
						|
 | 
						|
    void set_disk_space_limits(const DiskSpaceLimits& new_limits)
 | 
						|
    {
 | 
						|
        std::lock_guard<std::mutex> guard(m_settings.lock);
 | 
						|
        m_settings.disk_space_limits = new_limits;
 | 
						|
    }
 | 
						|
 | 
						|
    bool persistent_conns_enabled() const override
 | 
						|
    {
 | 
						|
        return m_settings.persistpoolmax > 0;
 | 
						|
    }
 | 
						|
 | 
						|
    void set_version(uint64_t version_num, const std::string& version_str) override;
 | 
						|
 | 
						|
    Version version() const override
 | 
						|
    {
 | 
						|
        return m_info.version_num();
 | 
						|
    }
 | 
						|
 | 
						|
    Type type() const override
 | 
						|
    {
 | 
						|
        return m_info.type();
 | 
						|
    }
 | 
						|
 | 
						|
    std::string version_string() const override
 | 
						|
    {
 | 
						|
        return m_info.version_string();
 | 
						|
    }
 | 
						|
 | 
						|
    const char* name() const override
 | 
						|
    {
 | 
						|
        return m_name.c_str();
 | 
						|
    }
 | 
						|
 | 
						|
    std::string protocol() const override
 | 
						|
    {
 | 
						|
        return m_settings.protocol;
 | 
						|
    }
 | 
						|
 | 
						|
    std::string get_authenticator() const
 | 
						|
    {
 | 
						|
        return m_settings.authenticator;
 | 
						|
    }
 | 
						|
 | 
						|
    int64_t rank() const override
 | 
						|
    {
 | 
						|
        return m_settings.rank;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Get a DCB from the persistent connection pool, if possible
 | 
						|
     *
 | 
						|
     * @param user        The name of the user needing the connection
 | 
						|
     * @param ip          Client IP address
 | 
						|
     * @param protocol    The name of the protocol needed for the connection
 | 
						|
     * @param id          Thread ID
 | 
						|
     *
 | 
						|
     * @return A DCB or NULL if no connection is found
 | 
						|
     */
 | 
						|
    DCB* get_persistent_dcb(const std::string& user, const std::string& ip, const std::string& protocol,
 | 
						|
                            int id);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Print server details to a dcb.
 | 
						|
     *
 | 
						|
     * @param dcb Dcb to print to
 | 
						|
     */
 | 
						|
    void print_to_dcb(DCB* dcb) const;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @brief Allocate a new server
 | 
						|
     *
 | 
						|
     * This will create a new server that represents a backend server that services
 | 
						|
     * can use. This function will add the server to the running configuration but
 | 
						|
     * will not persist the changes.
 | 
						|
     *
 | 
						|
     * @param name   Unique server name
 | 
						|
     * @param params Parameters for the server
 | 
						|
     *
 | 
						|
     * @return       The newly created server or NULL if an error occurred
 | 
						|
     */
 | 
						|
    static Server* server_alloc(const char* name, const MXS_CONFIG_PARAMETER& params);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Creates a server without any configuration. This should be used in unit tests in place of
 | 
						|
     * a default ctor.
 | 
						|
     *
 | 
						|
     * @return A new server
 | 
						|
     */
 | 
						|
    static Server* create_test_server();
 | 
						|
 | 
						|
    /**
 | 
						|
     * Deallocate the specified server
 | 
						|
     *
 | 
						|
     * @param server        The server to deallocate
 | 
						|
     * @return Returns true if the server was freed
 | 
						|
     */
 | 
						|
    static void server_free(Server* server);
 | 
						|
 | 
						|
    /**
 | 
						|
     * @brief Find a server with the specified name
 | 
						|
     *
 | 
						|
     * @param name Name of the server
 | 
						|
     * @return The server or NULL if not found
 | 
						|
     */
 | 
						|
    static Server* find_by_unique_name(const std::string& name);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Test if name is not a normal server setting name.
 | 
						|
     *
 | 
						|
     * @param name Name to check
 | 
						|
     * @return True if name is not a standard parameter
 | 
						|
     */
 | 
						|
    bool is_custom_parameter(const std::string& name) const;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Print server details to a DCB
 | 
						|
     *
 | 
						|
     * Designed to be called within a debugger session in order
 | 
						|
     * to display all active servers within the gateway
 | 
						|
     */
 | 
						|
    static void dprintServer(DCB*, const Server*);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Diagnostic to print number of DCBs in persistent pool for a server
 | 
						|
     *
 | 
						|
     * @param       pdcb    DCB to print results to
 | 
						|
     * @param       server  SERVER for which DCBs are to be printed
 | 
						|
     */
 | 
						|
    static void dprintPersistentDCBs(DCB*, const Server*);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Print all servers to a DCB
 | 
						|
     *
 | 
						|
     * Designed to be called within a debugger session in order
 | 
						|
     * to display all active servers within the gateway
 | 
						|
     */
 | 
						|
    static void dprintAllServers(DCB*);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Print all servers in Json format to a DCB
 | 
						|
     */
 | 
						|
    static void dprintAllServersJson(DCB*);
 | 
						|
 | 
						|
    /**
 | 
						|
     * List all servers in a tabular form to a DCB
 | 
						|
     *
 | 
						|
     */
 | 
						|
    static void dListServers(DCB*);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Convert all servers into JSON format
 | 
						|
     *
 | 
						|
     * @param host    Hostname of this server
 | 
						|
     * @return JSON array of servers or NULL if an error occurred
 | 
						|
     */
 | 
						|
    static json_t* server_list_to_json(const char* host);
 | 
						|
 | 
						|
    static bool create_server_config(const Server* server, const char* filename);
 | 
						|
 | 
						|
    static json_t* server_json_attributes(const Server* server);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Set server custom parameter.
 | 
						|
     *
 | 
						|
     * @param name   Parameter to set
 | 
						|
     * @param value  Value of parameter
 | 
						|
     */
 | 
						|
    void set_custom_parameter(const std::string& name, const std::string& value);
 | 
						|
 | 
						|
    std::string get_custom_parameter(const std::string& name) const override;
 | 
						|
 | 
						|
    void set_normal_parameter(const std::string& name, const std::string& value);
 | 
						|
 | 
						|
    /**
 | 
						|
     * @brief Serialize a server to a file
 | 
						|
     *
 | 
						|
     * This converts @c server into an INI format file. This allows created servers
 | 
						|
     * to be persisted to disk. This will replace any existing files with the same
 | 
						|
     * name.
 | 
						|
     *
 | 
						|
     * @return False if the serialization of the server fails, true if it was successful
 | 
						|
     */
 | 
						|
    bool serialize() const;
 | 
						|
 | 
						|
    /**
 | 
						|
     * Update server-specific monitor username. Does not affect existing monitor connections,
 | 
						|
     * only new connections will use the updated username.
 | 
						|
     *
 | 
						|
     * @param username New username. Must not be too long.
 | 
						|
     * @return True, if value was updated
 | 
						|
     */
 | 
						|
    bool set_monitor_user(const std::string& user);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Update server-specific monitor password. Does not affect existing monitor connections,
 | 
						|
     * only new connections will use the updated password.
 | 
						|
     *
 | 
						|
     * @param password New password. Must not be too long.
 | 
						|
     * @return True, if value was updated
 | 
						|
     */
 | 
						|
    bool set_monitor_password(const std::string& password);
 | 
						|
 | 
						|
    std::string monitor_user() const;
 | 
						|
    std::string monitor_password() const;
 | 
						|
 | 
						|
    /**
 | 
						|
     * @brief Set the disk space threshold of the server
 | 
						|
     *
 | 
						|
     * @param server                The server.
 | 
						|
     * @param disk_space_threshold  The disk space threshold as specified in the config file.
 | 
						|
     *
 | 
						|
     * @return True, if the provided string is valid and the threshold could be set.
 | 
						|
     */
 | 
						|
    bool set_disk_space_threshold(const std::string& disk_space_threshold);
 | 
						|
 | 
						|
    /**
 | 
						|
     * Print all servers
 | 
						|
     *
 | 
						|
     * Designed to be called within a debugger session in order
 | 
						|
     * to display all active servers within the gateway
 | 
						|
     */
 | 
						|
    static void printAllServers();
 | 
						|
 | 
						|
    /**
 | 
						|
     * Print details of an individual server
 | 
						|
     */
 | 
						|
    void printServer();
 | 
						|
 | 
						|
    static std::unique_ptr<ResultSet> getList();
 | 
						|
 | 
						|
    /**
 | 
						|
     * @brief Convert a server to JSON format
 | 
						|
     *
 | 
						|
     * @param host Hostname of this server as given in request
 | 
						|
     * @return JSON representation of server or NULL if an error occurred
 | 
						|
     */
 | 
						|
    json_t* to_json(const char* host);
 | 
						|
 | 
						|
    void* auth_instance()
 | 
						|
    {
 | 
						|
        return m_auth_instance;
 | 
						|
    }
 | 
						|
 | 
						|
    DCB** persistent = nullptr;     /**< List of unused persistent connections to the server */
 | 
						|
 | 
						|
private:
 | 
						|
    struct Settings
 | 
						|
    {
 | 
						|
        mutable std::mutex lock;    /**< Protects array-like settings from concurrent access */
 | 
						|
 | 
						|
        /** All config settings in text form. This is only read and written from the admin thread
 | 
						|
         *  so no need for locking. */
 | 
						|
        MXS_CONFIG_PARAMETER all_parameters;
 | 
						|
 | 
						|
        std::string protocol;       /**< Backend protocol module name. Does not change so needs no locking. */
 | 
						|
        std::string authenticator;  /**< Authenticator module name. Does not change so needs no locking. */
 | 
						|
 | 
						|
        char monuser[MAX_MONUSER_LEN + 1] = {'\0'}; /**< Monitor username, overrides monitor setting */
 | 
						|
        char monpw[MAX_MONPW_LEN + 1] = {'\0'};     /**< Monitor password, overrides monitor setting */
 | 
						|
 | 
						|
        long persistpoolmax = 0;    /**< Maximum size of persistent connections pool */
 | 
						|
        long persistmaxtime = 0;    /**< Maximum number of seconds connection can live */
 | 
						|
 | 
						|
        int64_t rank;   /*< The ranking of this server, used to prioritize certain servers over others */
 | 
						|
 | 
						|
        /** Disk space thresholds. Can be queried from modules at any time so access must be protected
 | 
						|
         *  by mutex. */
 | 
						|
        DiskSpaceLimits disk_space_limits;
 | 
						|
 | 
						|
        /** Additional custom parameters which may affect routing decisions or a monitor.
 | 
						|
         *  Can be queried from modules at any time so access must be protected by mutex. */
 | 
						|
        MXS_CONFIG_PARAMETER custom_parameters;
 | 
						|
    };
 | 
						|
 | 
						|
    /**
 | 
						|
     * Stores server version info. Encodes/decodes to/from the version number received from the server.
 | 
						|
     * Also stores the version string and parses information from it. */
 | 
						|
    class VersionInfo
 | 
						|
    {
 | 
						|
    public:
 | 
						|
 | 
						|
        /**
 | 
						|
         * Reads in version data. Deduces server type from version string.
 | 
						|
         *
 | 
						|
         * @param version_num Version number from server
 | 
						|
         * @param version_string Version string from server
 | 
						|
         */
 | 
						|
        void set(uint64_t version_num, const std::string& version_string);
 | 
						|
 | 
						|
        Version     version_num() const;
 | 
						|
        Type        type() const;
 | 
						|
        std::string version_string() const;
 | 
						|
 | 
						|
    private:
 | 
						|
        mutable std::mutex m_lock;      /**< Protects against concurrent writing */
 | 
						|
 | 
						|
        Version m_version_num;                              /**< Numeric version */
 | 
						|
        Type    m_type = Type::MARIADB;                     /**< Server type */
 | 
						|
        char    m_version_str[MAX_VERSION_LEN + 1] = {'\0'};/**< Server version string */
 | 
						|
    };
 | 
						|
 | 
						|
    const std::string m_name;               /**< Server config name */
 | 
						|
    Settings          m_settings;           /**< Server settings */
 | 
						|
    VersionInfo       m_info;               /**< Server version and type information */
 | 
						|
 | 
						|
    void* m_auth_instance = nullptr;    /**< Authenticator instance data */
 | 
						|
};
 |