Move listener parameter handling into Listener::create

The Listener::create method now takes a set of configuration parameters
from which it constructs a listener. This removes the duplicated code and
makes the behavior of listener creation similar to other objects in
MaxScale. It also allows the configuration parameters to be stored in the
listener object itself.
This commit is contained in:
Markus Mäkelä
2019-05-08 09:39:19 +03:00
parent ca21d27c68
commit 3813c728b1
12 changed files with 214 additions and 207 deletions

View File

@ -52,25 +52,15 @@ public:
/** /**
* Create a new listener * Create a new listener
* *
* @param service Service where the listener points to * @param name Name of the listener
* @param name Name of the listener * @param protocol Protocol module to use
* @param protocol Protocol module to use * @param params Parameters for the listener
* @param address The address to listen with
* @param port The port to listen on
* @param authenticator Name of the authenticator to be used
* @param auth_options Authenticator options
* @param ssl SSL configuration
* *
* @return New listener or nullptr on error * @return New listener or nullptr on error
*/ */
static SListener create(SERVICE* service, static SListener create(const std::string& name,
const std::string& name,
const std::string& protocol, const std::string& protocol,
const std::string& address, const MXS_CONFIG_PARAMETER& params);
unsigned short port,
const std::string& authenticator,
const std::string& auth_options,
SSL_LISTENER* ssl);
/** /**
* Destroy a listener * Destroy a listener
@ -211,20 +201,21 @@ private:
DESTROYED DESTROYED
}; };
std::string m_name; /**< Name of the listener */ std::string m_name; /**< Name of the listener */
State m_state; /**< Listener state */ State m_state; /**< Listener state */
std::string m_protocol; /**< Protocol module to load */ std::string m_protocol; /**< Protocol module to load */
uint16_t m_port; /**< Port to listen on */ uint16_t m_port; /**< Port to listen on */
std::string m_address; /**< Address to listen with */ std::string m_address; /**< Address to listen with */
std::string m_authenticator; /**< Name of authenticator */ std::string m_authenticator; /**< Name of authenticator */
std::string m_auth_options; /**< Authenticator options */ std::string m_auth_options; /**< Authenticator options */
void* m_auth_instance; /**< Authenticator instance */ void* m_auth_instance; /**< Authenticator instance */
SSL_LISTENER* m_ssl; /**< Structure of SSL data or NULL */ SSL_LISTENER* m_ssl; /**< Structure of SSL data or NULL */
struct users* m_users; /**< The user data for this listener */ struct users* m_users; /**< The user data for this listener */
SERVICE* m_service; /**< The service which used by this listener */ SERVICE* m_service; /**< The service which used by this listener */
std::atomic<bool> m_active; /**< True if the port has not been deleted */ std::atomic<bool> m_active; /**< True if the port has not been deleted */
MXS_PROTOCOL m_proto_func; /**< Preloaded protocol functions */ MXS_PROTOCOL m_proto_func; /**< Preloaded protocol functions */
MXS_AUTHENTICATOR m_auth_func; /**< Preloaded authenticator functions */ MXS_AUTHENTICATOR m_auth_func; /**< Preloaded authenticator functions */
MXS_CONFIG_PARAMETER m_params; /**< Configuration parameters */
Type m_type; /**< The type of the listener */ Type m_type; /**< The type of the listener */
@ -258,7 +249,8 @@ private:
*/ */
Listener(SERVICE* service, const std::string& name, const std::string& address, uint16_t port, Listener(SERVICE* service, const std::string& name, const std::string& address, uint16_t port,
const std::string& protocol, const std::string& authenticator, const std::string& protocol, const std::string& authenticator,
const std::string& auth_opts, void* auth_instance, SSL_LISTENER* ssl); const std::string& auth_opts, void* auth_instance, SSL_LISTENER* ssl,
const MXS_CONFIG_PARAMETER& params);
/** /**
* Listen on a file descriptor shared between all workers * Listen on a file descriptor shared between all workers

View File

@ -2887,22 +2887,22 @@ static void free_ssl_structure(SSL_LISTENER* ssl)
} }
bool config_create_ssl(const char* name, bool config_create_ssl(const char* name,
MXS_CONFIG_PARAMETER* params, const MXS_CONFIG_PARAMETER& params,
bool require_cert, bool require_cert,
SSL_LISTENER** dest) SSL_LISTENER** dest)
{ {
SSL_LISTENER* ssl = NULL; SSL_LISTENER* ssl = NULL;
// The enum values convert to bool // The enum values convert to bool
int value = params->get_enum(CN_SSL, ssl_values); int value = params.get_enum(CN_SSL, ssl_values);
mxb_assert(value != -1); mxb_assert(value != -1);
if (value) if (value)
{ {
bool error = false; bool error = false;
string ssl_cert = params->get_string(CN_SSL_CERT); string ssl_cert = params.get_string(CN_SSL_CERT);
string ssl_key = params->get_string(CN_SSL_KEY); string ssl_key = params.get_string(CN_SSL_KEY);
string ssl_ca_cert = params->get_string(CN_SSL_CA_CERT); string ssl_ca_cert = params.get_string(CN_SSL_CA_CERT);
if (ssl_ca_cert.empty()) if (ssl_ca_cert.empty())
{ {
@ -2942,12 +2942,12 @@ bool config_create_ssl(const char* name,
ssl = (SSL_LISTENER*)MXS_CALLOC(1, sizeof(SSL_LISTENER)); ssl = (SSL_LISTENER*)MXS_CALLOC(1, sizeof(SSL_LISTENER));
MXS_ABORT_IF_NULL(ssl); MXS_ABORT_IF_NULL(ssl);
int ssl_version = params->get_enum(CN_SSL_VERSION, ssl_version_values); int ssl_version = params.get_enum(CN_SSL_VERSION, ssl_version_values);
ssl->ssl_method_type = (ssl_method_type_t)ssl_version; ssl->ssl_method_type = (ssl_method_type_t)ssl_version;
ssl->ssl_init_done = false; ssl->ssl_init_done = false;
ssl->ssl_cert_verify_depth = params->get_integer(CN_SSL_CERT_VERIFY_DEPTH); ssl->ssl_cert_verify_depth = params.get_integer(CN_SSL_CERT_VERIFY_DEPTH);
ssl->ssl_verify_peer_certificate = params->get_bool(CN_SSL_VERIFY_PEER_CERTIFICATE); ssl->ssl_verify_peer_certificate = params.get_bool(CN_SSL_VERIFY_PEER_CERTIFICATE);
listener_set_certificates(ssl, ssl_cert, ssl_key, ssl_ca_cert); listener_set_certificates(ssl, ssl_cert, ssl_key, ssl_ca_cert);
@ -4130,86 +4130,7 @@ int create_new_listener(CONFIG_CONTEXT* obj)
return 1; return 1;
} }
int error_count = 0; return Listener::create(obj->name(), protocol, obj->m_parameters) ? 0 : 1;
bool port_defined = obj->m_parameters.contains(CN_PORT);
bool socket_defined = obj->m_parameters.contains(CN_SOCKET);
if (port_defined && socket_defined)
{
MXS_ERROR("Creation of listener '%s' failed because both 'socket' and 'port' "
"are defined. Only one of them is allowed.",
obj->name());
error_count++;
}
else if (!port_defined && !socket_defined)
{
MXS_ERROR("Listener '%s' is missing a required parameter. A Listener "
"must have a service, protocol and port (or socket) defined.",
obj->name());
error_count++;
}
else
{
auto address = obj->m_parameters.get_string(CN_ADDRESS);
Service* service = static_cast<Service*>(obj->m_parameters.get_service(CN_SERVICE));
mxb_assert(service);
// The conditionals just enforce defaults expected in the function.
auto port = port_defined ? obj->m_parameters.get_integer(CN_PORT) : 0;
auto socket = socket_defined ? obj->m_parameters.get_string(CN_SOCKET) : "";
// Remove this once maxadmin is removed
if (strcasecmp(protocol.c_str(), "maxscaled") == 0 && socket_defined
&& socket == MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG)
{
socket = MAXADMIN_DEFAULT_SOCKET;
address = "";
}
if (socket_defined)
{
if (auto l = listener_find_by_socket(socket))
{
MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
"listener '%s' already listens on socket %s.",
obj->name(), service->name(), l->name(), socket.c_str());
return 1;
}
}
else if (auto l = listener_find_by_address(address, port))
{
MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
"listener '%s' already listens on port %s.",
obj->name(), service->name(), l->name(),
obj->m_parameters.get_string(CN_PORT).c_str());
return 1;
}
auto protocol = obj->m_parameters.get_string(CN_PROTOCOL);
SSL_LISTENER* ssl_info = NULL;
if (!config_create_ssl(obj->name(), &obj->m_parameters, true, &ssl_info))
{
return 1;
}
// These two values being NULL trigger the loading of the default
// authenticators that are specific to each protocol module
auto authenticator = obj->m_parameters.get_string(CN_AUTHENTICATOR);
auto authenticator_options = obj->m_parameters.get_string(CN_AUTHENTICATOR_OPTIONS);
int net_port = socket_defined ? 0 : port;
auto listener = Listener::create(service, obj->name(), protocol, socket_defined ? socket : address,
net_port, authenticator, authenticator_options, ssl_info);
if (!listener)
{
++error_count;
}
}
return error_count;
} }
/** /**

View File

@ -470,7 +470,7 @@ static SSL_LISTENER* create_ssl(const char* name,
&& (!depth || config_add_param(obj, CN_SSL_CERT_VERIFY_DEPTH, depth)) && (!depth || config_add_param(obj, CN_SSL_CERT_VERIFY_DEPTH, depth))
&& (!verify || config_add_param(obj, CN_SSL_VERIFY_PEER_CERTIFICATE, verify))) && (!verify || config_add_param(obj, CN_SSL_VERIFY_PEER_CERTIFICATE, verify)))
{ {
config_create_ssl(name, &obj->m_parameters, true, &rval); config_create_ssl(name, obj->m_parameters, true, &rval);
} }
config_context_free(obj); config_context_free(obj);
@ -1155,31 +1155,14 @@ bool runtime_create_listener(Service* service,
const char* ssl_depth, const char* ssl_depth,
const char* verify_ssl) const char* verify_ssl)
{ {
if (addr == NULL || strcasecmp(addr, CN_DEFAULT) == 0)
{
addr = "::";
}
if (port == NULL || strcasecmp(port, CN_DEFAULT) == 0)
{
port = "3306";
}
if (proto == NULL || strcasecmp(proto, CN_DEFAULT) == 0) if (proto == NULL || strcasecmp(proto, CN_DEFAULT) == 0)
{ {
proto = "mariadbclient"; proto = "mariadbclient";
} }
if (!auth || strcasecmp(auth, CN_DEFAULT) == 0) MXS_CONFIG_PARAMETER params;
{ bool ok;
/** Use protocol default authenticator*/ tie(ok, params) = load_defaults(proto, MODULE_PROTOCOL, CN_LISTENER);
auth = "";
}
if (!auth_opt || strcasecmp(auth_opt, CN_DEFAULT) == 0)
{
/** Don't pass options to the authenticator */
auth_opt = "";
}
unsigned short u_port = atoi(port); unsigned short u_port = atoi(port);
bool rval = false; bool rval = false;
@ -1187,7 +1170,11 @@ bool runtime_create_listener(Service* service,
std::lock_guard<std::mutex> guard(crt_lock); std::lock_guard<std::mutex> guard(crt_lock);
std::string reason; std::string reason;
if (listener_find(name)) if (!ok)
{
config_runtime_error("Failed to load module '%s'", proto);
}
else if (listener_find(name))
{ {
config_runtime_error("Listener '%s' already exists", name); config_runtime_error("Listener '%s' already exists", name);
} }
@ -1197,49 +1184,50 @@ bool runtime_create_listener(Service* service,
} }
else if (config_is_valid_name(name, &reason)) else if (config_is_valid_name(name, &reason))
{ {
SSL_LISTENER* ssl = NULL; if (addr == NULL || strcasecmp(addr, CN_DEFAULT) == 0)
if (ssl_key && ssl_cert && ssl_ca
&& (ssl =
create_ssl(name,
ssl_key,
ssl_cert,
ssl_ca,
ssl_version,
ssl_depth,
verify_ssl)) == NULL)
{ {
MXS_ERROR("SSL initialization for listener '%s' failed.", name); params.set(CN_ADDRESS, "::");
config_runtime_error("SSL initialization for listener '%s' failed.", name);
} }
else
if (port == NULL || strcasecmp(port, CN_DEFAULT) == 0)
{ {
const char* print_addr = addr ? addr : "::"; params.set(CN_PORT, "3306");
auto listener = Listener::create(service, name, proto, addr, u_port, auth, auth_opt, ssl); }
if (listener && listener_serialize(listener)) if (auth && strcasecmp(auth, CN_DEFAULT) != 0)
{
params.set(CN_AUTHENTICATOR, auth);
}
if (auth_opt && strcasecmp(auth_opt, CN_DEFAULT) != 0)
{
params.set(CN_AUTHENTICATOR_OPTIONS, auth_opt);
}
const char* print_addr = addr ? addr : "::";
auto listener = Listener::create(name, proto, params);
if (listener && listener_serialize(listener))
{
if (listener->listen())
{ {
MXS_NOTICE("Created %slistener '%s' at %s:%s for service '%s'", MXS_NOTICE("Created listener '%s' at %s:%u for service '%s'",
ssl ? "TLS encrypted " : "", name, print_addr, port, service->name()); name, listener->address(), listener->port(), service->name());
if (listener->listen()) rval = true;
{
rval = true;
}
else
{
MXS_ERROR("Listener '%s' was created but failed to start it.", name);
config_runtime_error("Listener '%s' was created but failed to start it.", name);
Listener::destroy(listener);
mxb_assert(!listener_find(name));
}
} }
else else
{ {
MXS_ERROR("Failed to create listener '%s' at %s:%s.", name, print_addr, port); config_runtime_error("Listener '%s' was created but failed to start it.", name);
config_runtime_error("Failed to create listener '%s' at %s:%s.", name, print_addr, port); Listener::destroy(listener);
mxb_assert(!listener_find(name));
} }
} }
else
{
MXS_ERROR("Failed to create listener '%s' at %s:%s.", name, print_addr, port);
config_runtime_error("Failed to create listener '%s' at %s:%s.", name, print_addr, port);
}
} }
else else
{ {

View File

@ -70,9 +70,9 @@ void config_set_global_defaults();
*/ */
void config_add_defaults(CONFIG_CONTEXT* ctx, const MXS_MODULE_PARAM* params); void config_add_defaults(CONFIG_CONTEXT* ctx, const MXS_MODULE_PARAM* params);
char* config_clean_string_list(const char* str); char* config_clean_string_list(const char* str);
bool config_load(const char*); bool config_load(const char*);
bool config_load_global(const char* filename); bool config_load_global(const char* filename);
/** /**
* @brief Creates an empty configuration context * @brief Creates an empty configuration context
@ -140,7 +140,7 @@ void config_remove_param(CONFIG_CONTEXT* obj, const char* name);
* @return True on success, false on error * @return True on success, false on error
*/ */
bool config_create_ssl(const char* name, bool config_create_ssl(const char* name,
MXS_CONFIG_PARAMETER* params, const MXS_CONFIG_PARAMETER& params,
bool require_cert, bool require_cert,
SSL_LISTENER** dest); SSL_LISTENER** dest);

View File

@ -29,6 +29,7 @@
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
#include <maxscale/maxadmin.h>
#include <maxscale/paths.h> #include <maxscale/paths.h>
#include <maxscale/ssl.hh> #include <maxscale/ssl.hh>
#include <maxscale/protocol.hh> #include <maxscale/protocol.hh>
@ -40,6 +41,7 @@
#include "internal/modules.hh" #include "internal/modules.hh"
#include "internal/session.hh" #include "internal/session.hh"
#include "internal/config.hh"
using Clock = std::chrono::steady_clock; using Clock = std::chrono::steady_clock;
using std::chrono::seconds; using std::chrono::seconds;
@ -99,9 +101,16 @@ private:
thread_local RateLimit rate_limit; thread_local RateLimit rate_limit;
} }
Listener::Listener(SERVICE* service, const std::string& name, const std::string& address, Listener::Listener(SERVICE* service,
uint16_t port, const std::string& protocol, const std::string& authenticator, const std::string& name,
const std::string& auth_opts, void* auth_instance, SSL_LISTENER* ssl) const std::string& address,
uint16_t port,
const std::string& protocol,
const std::string& authenticator,
const std::string& auth_opts,
void* auth_instance,
SSL_LISTENER* ssl,
const MXS_CONFIG_PARAMETER& params)
: MXB_POLL_DATA{Listener::poll_handler} : MXB_POLL_DATA{Listener::poll_handler}
, m_name(name) , m_name(name)
, m_state(CREATED) , m_state(CREATED)
@ -116,6 +125,7 @@ Listener::Listener(SERVICE* service, const std::string& name, const std::string&
, m_service(service) , m_service(service)
, m_proto_func(*(MXS_PROTOCOL*)load_module(protocol.c_str(), MODULE_PROTOCOL)) , m_proto_func(*(MXS_PROTOCOL*)load_module(protocol.c_str(), MODULE_PROTOCOL))
, m_auth_func(*(MXS_AUTHENTICATOR*)load_module(authenticator.c_str(), MODULE_AUTHENTICATOR)) , m_auth_func(*(MXS_AUTHENTICATOR*)load_module(authenticator.c_str(), MODULE_AUTHENTICATOR))
, m_params(params)
{ {
if (strcasecmp(service->router_name(), "cli") == 0 || strcasecmp(service->router_name(), "maxinfo") == 0) if (strcasecmp(service->router_name(), "cli") == 0 || strcasecmp(service->router_name(), "maxinfo") == 0)
{ {
@ -145,15 +155,75 @@ Listener::~Listener()
SSL_LISTENER_free(m_ssl); SSL_LISTENER_free(m_ssl);
} }
SListener Listener::create(SERVICE* service, SListener Listener::create(const std::string& name,
const std::string& name,
const std::string& protocol, const std::string& protocol,
const std::string& address, const MXS_CONFIG_PARAMETER& params)
unsigned short port,
const std::string& authenticator,
const std::string& auth_options,
SSL_LISTENER* ssl)
{ {
bool port_defined = params.contains(CN_PORT);
bool socket_defined = params.contains(CN_SOCKET);
Service* service = static_cast<Service*>(params.get_service(CN_SERVICE));
if (port_defined && socket_defined)
{
MXS_ERROR("Creation of listener '%s' failed because both 'socket' and 'port' "
"are defined. Only one of them is allowed.",
name.c_str());
return nullptr;
}
else if ((!port_defined && !socket_defined) || !service)
{
MXS_ERROR("Listener '%s' is missing a required parameter. A Listener "
"must have a service, protocol and port (or socket) defined.",
name.c_str());
return nullptr;
}
// The conditionals just enforce defaults expected in the function.
auto port = port_defined ? params.get_integer(CN_PORT) : 0;
auto socket = socket_defined ? params.get_string(CN_SOCKET) : "";
auto address = socket_defined ? params.get_string(CN_SOCKET) : params.get_string(CN_ADDRESS);
// Remove this once maxadmin is removed
if (strcasecmp(protocol.c_str(), "maxscaled") == 0 && socket_defined
&& socket == MAXADMIN_CONFIG_DEFAULT_SOCKET_TAG)
{
socket = MAXADMIN_DEFAULT_SOCKET;
address = "";
}
if (socket_defined)
{
if (auto l = listener_find_by_socket(socket))
{
MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
"listener '%s' already listens on socket %s.",
name.c_str(), service->name(), l->name(), socket.c_str());
return nullptr;
}
}
else if (auto l = listener_find_by_address(address, port))
{
MXS_ERROR("Creation of listener '%s' for service '%s' failed, because "
"listener '%s' already listens on port %s.",
name.c_str(), service->name(), l->name(),
params.get_string(CN_PORT).c_str());
return nullptr;
}
SSL_LISTENER* ssl_info = NULL;
if (!config_create_ssl(name.c_str(), params, true, &ssl_info))
{
return nullptr;
}
// These two values being NULL trigger the loading of the default
// authenticators that are specific to each protocol module
auto authenticator = params.get_string(CN_AUTHENTICATOR);
auto authenticator_options = params.get_string(CN_AUTHENTICATOR_OPTIONS);
int net_port = socket_defined ? 0 : port;
const char* auth = !authenticator.empty() ? authenticator.c_str() : const char* auth = !authenticator.empty() ? authenticator.c_str() :
get_default_authenticator(protocol.c_str()); get_default_authenticator(protocol.c_str());
@ -166,7 +236,7 @@ SListener Listener::create(SERVICE* service,
void* auth_instance = NULL; void* auth_instance = NULL;
if (!authenticator_init(&auth_instance, auth, auth_options.c_str())) if (!authenticator_init(&auth_instance, auth, authenticator_options.c_str()))
{ {
MXS_ERROR("Failed to initialize authenticator module '%s' for listener '%s'.", MXS_ERROR("Failed to initialize authenticator module '%s' for listener '%s'.",
auth, name.c_str()); auth, name.c_str());
@ -179,7 +249,7 @@ SListener Listener::create(SERVICE* service,
mxb_assert(proto_mod && auth_mod); mxb_assert(proto_mod && auth_mod);
SListener listener(new(std::nothrow) Listener(service, name, address, port, protocol, auth, SListener listener(new(std::nothrow) Listener(service, name, address, port, protocol, auth,
auth_options, auth_instance, ssl)); authenticator_options, auth_instance, ssl_info, params));
if (listener) if (listener)
{ {

View File

@ -197,7 +197,7 @@ Server* Server::server_alloc(const char* name, MXS_CONFIG_PARAMETER* params)
SSL_LISTENER* ssl = NULL; SSL_LISTENER* ssl = NULL;
if (!config_create_ssl(name, params, false, &ssl)) if (!config_create_ssl(name, *params, false, &ssl))
{ {
MXS_ERROR("Unable to initialize SSL for server '%s'", name); MXS_ERROR("Unable to initialize SSL for server '%s'", name);
return NULL; return NULL;

View File

@ -54,7 +54,15 @@ static int test1()
parameters.set("max_retry_interval", "10s"); parameters.set("max_retry_interval", "10s");
parameters.set("connection_timeout", "10s"); parameters.set("connection_timeout", "10s");
auto service = service_alloc("service", "readconnroute", &parameters); auto service = service_alloc("service", "readconnroute", &parameters);
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306, "", "", nullptr);
MXS_CONFIG_PARAMETER listener_params;
listener_params.set(CN_ADDRESS, "0.0.0.0");
listener_params.set(CN_PORT, "3306");
listener_params.set(CN_PROTOCOL, "mariadbclient");
listener_params.set(CN_SERVICE, service->name());
auto listener = Listener::create("listener", "mariadbclient", listener_params);
auto session = new mxs::Session(listener); auto session = new mxs::Session(listener);
dcb = dcb_alloc(DCB::Role::INTERNAL, session); dcb = dcb_alloc(DCB::Role::INTERNAL, session);
printDCB(dcb); printDCB(dcb);

View File

@ -60,7 +60,15 @@ static int test1()
parameters.set(CN_MAX_RETRY_INTERVAL, "10s"); parameters.set(CN_MAX_RETRY_INTERVAL, "10s");
parameters.set(CN_CONNECTION_TIMEOUT, "10s"); parameters.set(CN_CONNECTION_TIMEOUT, "10s");
auto service = service_alloc("service", "readconnroute", &parameters); auto service = service_alloc("service", "readconnroute", &parameters);
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306, "", "", nullptr);
MXS_CONFIG_PARAMETER listener_params;
listener_params.set(CN_ADDRESS, "0.0.0.0");
listener_params.set(CN_PORT, "3306");
listener_params.set(CN_PROTOCOL, "mariadbclient");
listener_params.set(CN_SERVICE, service->name());
auto listener = Listener::create("listener", "mariadbclient", listener_params);
auto session = new mxs::Session(listener); auto session = new mxs::Session(listener);
dcb = dcb_alloc(DCB::Role::CLIENT, session); dcb = dcb_alloc(DCB::Role::CLIENT, session);

View File

@ -78,14 +78,14 @@ static int test1()
mxb_assert_message(0 != service_isvalid(service), "Service must be valid after creation"); mxb_assert_message(0 != service_isvalid(service), "Service must be valid after creation");
mxb_assert_message(0 == strcmp("MyService", service->name()), "Service must have given name"); mxb_assert_message(0 == strcmp("MyService", service->name()), "Service must have given name");
fprintf(stderr, "\t..done\nAdding protocol testprotocol."); fprintf(stderr, "\t..done\nAdding protocol testprotocol.");
mxb_assert_message(Listener::create(service,
"TestProtocol", MXS_CONFIG_PARAMETER listener_params;
"mariadbclient", listener_params.set(CN_ADDRESS, "localhost");
"localhost", listener_params.set(CN_PORT, "9876");
9876, listener_params.set(CN_PROTOCOL, "mariadbclient");
"MySQLAuth", listener_params.set(CN_SERVICE, service->name());
"",
NULL), mxb_assert_message(Listener::create("TestProtocol", "mariadbclient", listener_params),
"Add Protocol should succeed"); "Add Protocol should succeed");
mxb_assert_message(service_find_listener(service, "", "localhost", 9876), mxb_assert_message(service_find_listener(service, "", "localhost", 9876),
"Service should have new protocol as requested"); "Service should have new protocol as requested");

View File

@ -141,7 +141,7 @@ string create_unique_select()
int test(mock::Session& session, int test(mock::Session& session,
FilterModule::Session& filter_session, FilterModule::Session& filter_session,
mock::RouterSession& router_session, mock::RouterSession& router_session,
const TEST_CASE& tc) const TEST_CASE& tc)
{ {
int rv = 0; int rv = 0;
@ -293,7 +293,15 @@ int test(FilterModule::Instance& filter_instance, const TEST_CASE& tc)
parameters.set("connection_timeout", "10s"); parameters.set("connection_timeout", "10s");
auto service = service_alloc("service", "readconnroute", &parameters); auto service = service_alloc("service", "readconnroute", &parameters);
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306, "", "", nullptr);
MXS_CONFIG_PARAMETER listener_params;
listener_params.set(CN_ADDRESS, "0.0.0.0");
listener_params.set(CN_PORT, "3306");
listener_params.set(CN_PROTOCOL, "mariadbclient");
listener_params.set(CN_SERVICE, service->name());
auto listener = Listener::create("listener", "mariadbclient", listener_params);
mock::Client client("bob", "127.0.0.1"); mock::Client client("bob", "127.0.0.1");
mock::Session session(&client, listener); mock::Session session(&client, listener);
mock::ResultSetBackend backend; mock::ResultSetBackend backend;

View File

@ -708,7 +708,7 @@ void log_error(const FW_TEST_CASE& c)
int test(mock::Client& client, int test(mock::Client& client,
FilterModule::Session& filter_session, FilterModule::Session& filter_session,
mock::RouterSession& router_session, mock::RouterSession& router_session,
const FW_TEST_CASE& c) const FW_TEST_CASE& c)
{ {
int rv = 0; int rv = 0;
@ -772,8 +772,15 @@ int test(FilterModule::Instance& filter_instance, const FW_TEST& t)
parameters.set("max_retry_interval", "10s"); parameters.set("max_retry_interval", "10s");
parameters.set("connection_timeout", "10s"); parameters.set("connection_timeout", "10s");
auto service = service_alloc("service", "readconnroute", &parameters); auto service = service_alloc("service", "readconnroute", &parameters);
auto listener = Listener::create(service, "listener", "mariadbclient", "0.0.0.0", 3306,
"", "", nullptr); MXS_CONFIG_PARAMETER listener_params;
listener_params.set(CN_ADDRESS, "0.0.0.0");
listener_params.set(CN_PORT, "3306");
listener_params.set(CN_PROTOCOL, "mariadbclient");
listener_params.set(CN_SERVICE, service->name());
auto listener = Listener::create("listener", "mariadbclient", listener_params);
mock::Session session(&client, listener); mock::Session session(&client, listener);
mock::OkBackend backend; mock::OkBackend backend;
mock::RouterSession router_session(&backend, &session); mock::RouterSession router_session(&backend, &session);

View File

@ -188,8 +188,13 @@ static void blr_start_master(void* data)
pthread_mutex_unlock(&router->lock); pthread_mutex_unlock(&router->lock);
// Create a temporary listener so we can create a session originating from it // Create a temporary listener so we can create a session originating from it
auto listener = Listener::create(router->service, "binlogrouter_listener", "mariadbclient", MXS_CONFIG_PARAMETER listener_params;
"127.0.0.1", 9999, "", "", nullptr); listener_params.set(CN_ADDRESS, "127.0.0.1");
listener_params.set(CN_PORT, "9999");
listener_params.set(CN_PROTOCOL, "mariadbclient");
listener_params.set(CN_SERVICE, router->service->name());
auto listener = Listener::create("binlogrouter_listener", "mariadbclient", listener_params);
mxb_assert(listener); mxb_assert(listener);
// Load users now so that authentication will work for the fake client // Load users now so that authentication will work for the fake client
@ -1708,7 +1713,7 @@ bool blr_send_event(blr_thread_role_t role,
const char* binlog_name, const char* binlog_name,
uint32_t binlog_pos, uint32_t binlog_pos,
ROUTER_SLAVE* slave, ROUTER_SLAVE* slave,
REP_HEADER* hdr, REP_HEADER* hdr,
uint8_t* buf) uint8_t* buf)
{ {
bool rval = true; bool rval = true;