277 lines
7.4 KiB
C
277 lines
7.4 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: 2020-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 <stdio.h>
|
|
#include <maxscale/filter.h>
|
|
#include <maxscale/alloc.h>
|
|
#include <maxscale/modinfo.h>
|
|
#include <maxscale/modutil.h>
|
|
#include <maxscale/atomic.h>
|
|
|
|
/**
|
|
* @file testfilter.c - a very simple test filter.
|
|
* @verbatim
|
|
*
|
|
* This filter is a very simple example used to test the filter API,
|
|
* it merely counts the number of statements that flow through the
|
|
* filter pipeline.
|
|
*
|
|
* Reporting is done via the diagnostics print routine.
|
|
* @endverbatim
|
|
*/
|
|
|
|
static MXS_FILTER *createInstance(const char *name, char **options, MXS_CONFIG_PARAMETER *params);
|
|
static MXS_FILTER_SESSION *newSession(MXS_FILTER *instance, MXS_SESSION *session);
|
|
static void closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
|
|
static void freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session);
|
|
static void setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, MXS_DOWNSTREAM *downstream);
|
|
static int routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, GWBUF *queue);
|
|
static void diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb);
|
|
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession);
|
|
static uint64_t getCapabilities(MXS_FILTER* instance);
|
|
static void destroyInstance(MXS_FILTER *instance);
|
|
|
|
/**
|
|
* A dummy instance structure
|
|
*/
|
|
typedef struct
|
|
{
|
|
const char *name;
|
|
int sessions;
|
|
} TEST_INSTANCE;
|
|
|
|
/**
|
|
* A dummy session structure for this test filter
|
|
*/
|
|
typedef struct
|
|
{
|
|
MXS_DOWNSTREAM down;
|
|
int count;
|
|
} TEST_SESSION;
|
|
|
|
/**
|
|
* The module entry point routine. It is this routine that
|
|
* must populate the structure that is referred to as the
|
|
* "module object", this is a structure with the set of
|
|
* external entry points for this module.
|
|
*
|
|
* @return The module object
|
|
*/
|
|
MXS_MODULE* MXS_CREATE_MODULE()
|
|
{
|
|
static MXS_FILTER_OBJECT MyObject =
|
|
{
|
|
createInstance,
|
|
newSession,
|
|
closeSession,
|
|
freeSession,
|
|
setDownstream,
|
|
NULL, // No upstream requirement
|
|
routeQuery,
|
|
NULL, // No clientReply
|
|
diagnostic,
|
|
diagnostic_json,
|
|
getCapabilities,
|
|
destroyInstance,
|
|
};
|
|
|
|
static MXS_MODULE info =
|
|
{
|
|
MXS_MODULE_API_FILTER,
|
|
MXS_MODULE_BETA_RELEASE,
|
|
MXS_FILTER_VERSION,
|
|
"A simple query counting filter",
|
|
"V2.0.0",
|
|
MXS_NO_MODULE_CAPABILITIES,
|
|
&MyObject,
|
|
NULL, /* Process init. */
|
|
NULL, /* Process finish. */
|
|
NULL, /* Thread init. */
|
|
NULL, /* Thread finish. */
|
|
{
|
|
{MXS_END_MODULE_PARAMS}
|
|
}
|
|
};
|
|
|
|
return &info;
|
|
}
|
|
|
|
/**
|
|
* Create an instance of the filter for a particular service
|
|
* within MaxScale.
|
|
*
|
|
* @param name The name of the instance (as defined in the config file).
|
|
* @param options The options for this filter
|
|
* @param params The array of name/value pair parameters for the filter
|
|
*
|
|
* @return The instance data for this new instance
|
|
*/
|
|
static MXS_FILTER *
|
|
createInstance(const char *name, char **options, MXS_CONFIG_PARAMETER *params)
|
|
{
|
|
TEST_INSTANCE *my_instance;
|
|
|
|
if ((my_instance = MXS_CALLOC(1, sizeof(TEST_INSTANCE))) != NULL)
|
|
{
|
|
my_instance->sessions = 0;
|
|
my_instance->name = name;
|
|
}
|
|
return (MXS_FILTER *)my_instance;
|
|
}
|
|
|
|
/**
|
|
* Associate a new session with this instance of the filter.
|
|
*
|
|
* @param instance The filter instance data
|
|
* @param session The session itself
|
|
* @return Session specific data for this session
|
|
*/
|
|
static MXS_FILTER_SESSION *
|
|
newSession(MXS_FILTER *instance, MXS_SESSION *session)
|
|
{
|
|
TEST_INSTANCE *my_instance = (TEST_INSTANCE *)instance;
|
|
TEST_SESSION *my_session;
|
|
|
|
if ((my_session = MXS_CALLOC(1, sizeof(TEST_SESSION))) != NULL)
|
|
{
|
|
atomic_add(&my_instance->sessions, 1);
|
|
my_session->count = 0;
|
|
}
|
|
|
|
return (MXS_FILTER_SESSION*)my_session;
|
|
}
|
|
|
|
/**
|
|
* Close a session with the filter, this is the mechanism
|
|
* by which a filter may cleanup data structure etc.
|
|
*
|
|
* @param instance The filter instance data
|
|
* @param session The session being closed
|
|
*/
|
|
static void
|
|
closeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
|
{
|
|
}
|
|
|
|
/**
|
|
* Free the memory associated with this filter session.
|
|
*
|
|
* @param instance The filter instance data
|
|
* @param session The session being closed
|
|
*/
|
|
static void
|
|
freeSession(MXS_FILTER *instance, MXS_FILTER_SESSION *session)
|
|
{
|
|
MXS_FREE(session);
|
|
}
|
|
|
|
/**
|
|
* Set the downstream component for this filter.
|
|
*
|
|
* @param instance The filter instance data
|
|
* @param session The session being closed
|
|
* @param downstream The downstream filter or router
|
|
*/
|
|
static void
|
|
setDownstream(MXS_FILTER *instance, MXS_FILTER_SESSION *session, MXS_DOWNSTREAM *downstream)
|
|
{
|
|
TEST_SESSION *my_session = (TEST_SESSION *)session;
|
|
|
|
my_session->down = *downstream;
|
|
}
|
|
|
|
/**
|
|
* The routeQuery entry point. This is passed the query buffer
|
|
* to which the filter should be applied. Once applied the
|
|
* query shoudl normally be passed to the downstream component
|
|
* (filter or router) in the filter chain.
|
|
*
|
|
* @param instance The filter instance data
|
|
* @param session The filter session
|
|
* @param queue The query data
|
|
*/
|
|
static int
|
|
routeQuery(MXS_FILTER *instance, MXS_FILTER_SESSION *session, GWBUF *queue)
|
|
{
|
|
TEST_SESSION *my_session = (TEST_SESSION *)session;
|
|
|
|
if (modutil_is_SQL(queue))
|
|
{
|
|
my_session->count++;
|
|
}
|
|
return my_session->down.routeQuery(my_session->down.instance,
|
|
my_session->down.session, queue);
|
|
}
|
|
|
|
/**
|
|
* Diagnostics routine
|
|
*
|
|
* If fsession is NULL then print diagnostics on the filter
|
|
* instance as a whole, otherwise print diagnostics for the
|
|
* particular session.
|
|
*
|
|
* @param instance The filter instance
|
|
* @param fsession Filter session, may be NULL
|
|
* @param dcb The DCB for diagnostic output
|
|
*/
|
|
static void
|
|
diagnostic(MXS_FILTER *instance, MXS_FILTER_SESSION *fsession, DCB *dcb)
|
|
{
|
|
TEST_INSTANCE *my_instance = (TEST_INSTANCE *)instance;
|
|
TEST_SESSION *my_session = (TEST_SESSION *)fsession;
|
|
|
|
if (my_session)
|
|
dcb_printf(dcb, "\t\tNo. of queries routed by filter: %d\n",
|
|
my_session->count);
|
|
else
|
|
dcb_printf(dcb, "\t\tNo. of sessions created: %d\n",
|
|
my_instance->sessions);
|
|
}
|
|
|
|
/**
|
|
* Diagnostics routine
|
|
*
|
|
* If fsession is NULL then print diagnostics on the filter
|
|
* instance as a whole, otherwise print diagnostics for the
|
|
* particular session.
|
|
*
|
|
* @param instance The filter instance
|
|
* @param fsession Filter session, may be NULL
|
|
* @param dcb The DCB for diagnostic output
|
|
*/
|
|
static json_t* diagnostic_json(const MXS_FILTER *instance, const MXS_FILTER_SESSION *fsession)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* Capability routine.
|
|
*
|
|
* @return The capabilities of the filter.
|
|
*/
|
|
static uint64_t getCapabilities(MXS_FILTER* instance)
|
|
{
|
|
return RCAP_TYPE_NONE;
|
|
}
|
|
|
|
/**
|
|
* destroyInstance routine.
|
|
*
|
|
* @param The filter instance.
|
|
*/
|
|
static void destroyInstance(MXS_FILTER *instance)
|
|
{
|
|
TEST_INSTANCE *cinstance = (TEST_INSTANCE *)instance;
|
|
|
|
MXS_INFO("Destroying filter %s", cinstance->name);
|
|
}
|