404 lines
11 KiB
C++
404 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: 2022-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.
|
|
*/
|
|
#pragma once
|
|
|
|
#include <maxscale/service.hh>
|
|
#include <maxscale/resultset.hh>
|
|
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "filter.hh"
|
|
|
|
/**
|
|
* @file service.h - MaxScale internal service functions
|
|
*/
|
|
|
|
struct LastUserLoad
|
|
{
|
|
time_t last = 0; // The last time the users were loaded
|
|
bool warned = false; // Has a warning been logged
|
|
};
|
|
|
|
// The internal service representation
|
|
class Service : public SERVICE
|
|
{
|
|
public:
|
|
using FilterList = std::vector<SFilterDef>;
|
|
using RateLimits = std::vector<LastUserLoad>;
|
|
|
|
Service(const std::string& name, const std::string& router, MXS_CONFIG_PARAMETER* params);
|
|
|
|
~Service();
|
|
|
|
/**
|
|
* Check if name matches a basic service parameter
|
|
*
|
|
* Basic parameters are common to all services. These include, for example, the
|
|
* `user` and `password` parameters.
|
|
*
|
|
* @return True if the parameter is a basic service parameter
|
|
*/
|
|
bool is_basic_parameter(const std::string& name);
|
|
|
|
/**
|
|
* Update a basic service parameter
|
|
*
|
|
* Update a parameter that is common to all services.
|
|
*
|
|
* @param name Name of the parameter to update
|
|
* @param value The new value of the parameter
|
|
*/
|
|
void update_basic_parameter(const std::string& name, const std::string& value);
|
|
|
|
/**
|
|
* Set the list of filters for this service
|
|
*
|
|
* @param filters Filters to set
|
|
*
|
|
* @return True if filters were all found and were valid
|
|
*/
|
|
bool set_filters(const std::vector<std::string>& filters);
|
|
|
|
/**
|
|
* Get the list of filters this service uses
|
|
*
|
|
* @note This can lock the service if this is the first time this worker
|
|
* accesses the filter list
|
|
*
|
|
* @return A list of filters or an empty list of no filters are in use
|
|
*/
|
|
const FilterList& get_filters() const;
|
|
|
|
/**
|
|
* Reload users for all listeners
|
|
*
|
|
* @return True if loading of users was successful
|
|
*/
|
|
bool refresh_users();
|
|
|
|
/**
|
|
* Dump service configuration into a file
|
|
*
|
|
* @param filename File where the configuration should be written
|
|
*
|
|
* @return True on success
|
|
*/
|
|
bool dump_config(const char* filename) const;
|
|
|
|
// TODO: Make JSON output internal (could iterate over get_filters() but that takes the service lock)
|
|
json_t* json_relationships(const char* host) const;
|
|
|
|
// TODO: Make these private
|
|
mutable std::mutex lock;
|
|
|
|
private:
|
|
FilterList m_filters; /**< Ordered list of filters */
|
|
std::string m_name; /**< Name of the service */
|
|
std::string m_router_name; /**< Router module */
|
|
std::string m_user; /**< Username */
|
|
std::string m_password; /**< Password */
|
|
std::string m_weightby; /**< Weighting parameter name */
|
|
std::string m_version_string; /**< Version string sent to clients */
|
|
RateLimits m_rate_limits; /**< The refresh rate limits for users of each thread */
|
|
uint64_t m_wkey; /**< Key for worker local data */
|
|
|
|
// Get the worker local filter list
|
|
FilterList* get_local_filters() const;
|
|
|
|
// Update the local filter list on the current worker
|
|
void update_local_filters();
|
|
|
|
// Callback for updating the local filter list
|
|
static void update_filters_cb(void* data)
|
|
{
|
|
Service* service = static_cast<Service*>(data);
|
|
service->update_local_filters();
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Service life cycle management
|
|
*
|
|
* These functions should only be called by the MaxScale core.
|
|
*/
|
|
|
|
/**
|
|
* @brief Allocate a new service
|
|
*
|
|
* @param name The service name
|
|
* @param router The router module this service uses
|
|
* @param params Service parameters
|
|
*
|
|
* @return The newly created service or NULL if an error occurred
|
|
*/
|
|
Service* service_alloc(const char* name, const char* router, MXS_CONFIG_PARAMETER* params);
|
|
|
|
/**
|
|
* Free a service
|
|
*
|
|
* @note Must not be called if the service has any active client connections or
|
|
* active listeners
|
|
*
|
|
* @param service Service to free
|
|
*/
|
|
void service_free(Service* service);
|
|
|
|
/**
|
|
* Mark a service for destruction
|
|
*
|
|
* Once the service reference count drops down to zero, the service is destroyed.
|
|
*
|
|
* @param service Service to destroy
|
|
*/
|
|
void service_destroy(Service* service);
|
|
|
|
/**
|
|
* Check whether a service can be destroyed
|
|
*
|
|
* @param service Service to check
|
|
*
|
|
* @return True if service can be destroyed
|
|
*/
|
|
bool service_can_be_destroyed(Service* service);
|
|
|
|
/**
|
|
* @brief Shut all services down
|
|
*
|
|
* Turns on the shutdown flag in each service. This should be done as
|
|
* part of the MaxScale shutdown.
|
|
*/
|
|
void service_shutdown(void);
|
|
|
|
/**
|
|
* @brief Destroy all service router and filter instances
|
|
*
|
|
* Calls the @c destroyInstance entry point of each service' router and
|
|
* filters. This should be done after all worker threads have exited.
|
|
*/
|
|
void service_destroy_instances(void);
|
|
|
|
/**
|
|
* @brief Launch all services
|
|
*
|
|
* Initialize and start all services. This should only be called once by the
|
|
* main initialization code.
|
|
*
|
|
* @return False if a fatal error occurred
|
|
*/
|
|
bool service_launch_all(void);
|
|
|
|
/**
|
|
* @brief Remove a listener from use
|
|
*
|
|
* @note This does not free the memory
|
|
*
|
|
* @param service Service that owns the listener
|
|
* @param char Name of the listener to remove
|
|
*
|
|
* @return True if listener was found and removed
|
|
*/
|
|
bool service_remove_listener(Service* service, const char* target);
|
|
|
|
void serviceRemoveBackend(Service* service, const SERVER* server);
|
|
|
|
/**
|
|
* @brief Serialize a service to a file
|
|
*
|
|
* This converts @c service into an INI format file.
|
|
*
|
|
* NOTE: This does not persist the complete service configuration and requires
|
|
* that an existing service configuration is in the main configuration file.
|
|
*
|
|
* @param service Service to serialize
|
|
* @return False if the serialization of the service fails, true if it was successful
|
|
*/
|
|
bool service_serialize(const Service* service);
|
|
|
|
/**
|
|
* Internal utility functions
|
|
*/
|
|
bool service_all_services_have_listeners(void);
|
|
bool service_isvalid(Service* service);
|
|
|
|
/**
|
|
* Check if a service uses @c servers
|
|
* @param server Server that is queried
|
|
* @return True if server is used by at least one service
|
|
*/
|
|
bool service_server_in_use(const SERVER* server);
|
|
|
|
/**
|
|
* Check if filter is used by any service
|
|
*
|
|
* @param filter Filter to inspect
|
|
*
|
|
* @return True if at least one service uses the filter
|
|
*/
|
|
bool service_filter_in_use(const SFilterDef& filter);
|
|
|
|
/** Update the server weights used by services */
|
|
void service_update_weights();
|
|
|
|
/**
|
|
* @brief Add parameters to a service
|
|
*
|
|
* A copy of @c param is added to @c service.
|
|
*
|
|
* @param service Service where the parameters are added
|
|
* @param param Parameters to add
|
|
*/
|
|
void service_add_parameters(Service* service, const MXS_CONFIG_PARAMETER* param);
|
|
|
|
/**
|
|
* @brief Add parameters to a service
|
|
*
|
|
* A copy of @c param is added to @c service.
|
|
*
|
|
* @param service Service where the parameters are added
|
|
* @param key Parameter name
|
|
* @param value Parameter value
|
|
*/
|
|
void service_add_parameter(Service* service, const char* key, const char* value);
|
|
|
|
/**
|
|
* @brief Remove service parameter
|
|
*
|
|
* @param service Service to modify
|
|
* @param key Parameter to remove
|
|
*/
|
|
void service_remove_parameter(Service* service, const char* key);
|
|
|
|
/**
|
|
* @brief Replace service parameter
|
|
*
|
|
* @param service Service to modify
|
|
* @param key Parameter name
|
|
* @param value Parameter value
|
|
*/
|
|
void service_replace_parameter(Service* service, const char* key, const char* value);
|
|
|
|
// Internal search function
|
|
Service* service_internal_find(const char* name);
|
|
|
|
/**
|
|
* @brief Check if a service uses a server
|
|
* @param service Service to check
|
|
* @param server Server being used
|
|
* @return True if service uses the server
|
|
*/
|
|
bool serviceHasBackend(Service* service, SERVER* server);
|
|
|
|
/**
|
|
* @brief Find listener with specified properties.
|
|
*
|
|
* @param service Service to check
|
|
* @param socket Listener socket path
|
|
* @param address Listener address
|
|
* @param port Listener port number
|
|
*
|
|
* @note Either socket should be NULL and port non-zero or socket
|
|
* non-NULL and port zero.
|
|
*
|
|
* @return True if service has the listener
|
|
*/
|
|
SListener service_find_listener(Service* service,
|
|
const std::string& socket,
|
|
const std::string& address,
|
|
unsigned short port);
|
|
|
|
/**
|
|
* @brief Check if a MaxScale service listens on a port
|
|
*
|
|
* @param port The port to check
|
|
* @return True if a MaxScale service uses the port
|
|
*/
|
|
bool service_port_is_used(int port);
|
|
|
|
/**
|
|
* @brief Check if the service has a listener with a matching name
|
|
*
|
|
* @param service Service to check
|
|
* @param name Name to compare to
|
|
*
|
|
* @return True if the service has a listener with a matching name
|
|
*/
|
|
bool service_has_named_listener(Service* service, const char* name);
|
|
|
|
// Required by MaxAdmin
|
|
int service_enable_root(Service* service, int action);
|
|
|
|
/**
|
|
* @brief Convert a service to JSON
|
|
*
|
|
* @param service Service to convert
|
|
* @param host Hostname of this server
|
|
*
|
|
* @return JSON representation of the service
|
|
*/
|
|
json_t* service_to_json(const Service* service, const char* host);
|
|
|
|
/**
|
|
* @brief Convert all services to JSON
|
|
*
|
|
* @param host Hostname of this server
|
|
*
|
|
* @return A JSON array with all services
|
|
*/
|
|
json_t* service_list_to_json(const char* host);
|
|
|
|
/**
|
|
* @brief Convert service listeners to JSON
|
|
*
|
|
* @param service Service whose listeners are converted
|
|
* @param host Hostname of this server
|
|
*
|
|
* @return Array of JSON format listeners
|
|
*/
|
|
json_t* service_listener_list_to_json(const Service* service, const char* host);
|
|
|
|
/**
|
|
* @brief Convert service listener to JSON
|
|
*
|
|
* @param service Service whose listener is converted
|
|
* @param name The name of the listener
|
|
* @param host Hostname of this server
|
|
*
|
|
* @return JSON format listener
|
|
*/
|
|
json_t* service_listener_to_json(const Service* service, const char* name, const char* host);
|
|
|
|
/**
|
|
* @brief Get links to services that relate to a server
|
|
*
|
|
* @param server Server to inspect
|
|
* @param host Hostname of this server
|
|
*
|
|
* @return Array of service links or NULL if no relations exist
|
|
*/
|
|
json_t* service_relations_to_server(const SERVER* server, const char* host);
|
|
|
|
/**
|
|
* @brief Get links to services that relate to a filter
|
|
*
|
|
* @param filter Filter to inspect
|
|
* @param host Hostname of this server
|
|
*
|
|
* @return Array of service links
|
|
*/
|
|
json_t* service_relations_to_filter(const SFilterDef& filter, const char* host);
|
|
|
|
std::unique_ptr<ResultSet> serviceGetList(void);
|
|
std::unique_ptr<ResultSet> serviceGetListenerList(void);
|