MXS-2302: Use filter template in hintfilter
This commit is contained in:
@ -26,17 +26,75 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static MXS_FILTER* createInstance(const char* name, MXS_CONFIG_PARAMETER* params);
|
// static
|
||||||
static MXS_FILTER_SESSION* newSession(MXS_FILTER* instance, MXS_SESSION* session);
|
HINT_INSTANCE* HINT_INSTANCE::create(const char* zName, MXS_CONFIG_PARAMETER* ppParams)
|
||||||
static void closeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session);
|
{
|
||||||
static void freeSession(MXS_FILTER* instance, MXS_FILTER_SESSION* session);
|
return new(std::nothrow) HINT_INSTANCE;
|
||||||
static void setDownstream(MXS_FILTER* instance,
|
}
|
||||||
MXS_FILTER_SESSION* fsession,
|
|
||||||
MXS_DOWNSTREAM* downstream);
|
HINT_SESSION* HINT_INSTANCE::newSession(MXS_SESSION* pSession)
|
||||||
static int routeQuery(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, GWBUF* queue);
|
{
|
||||||
static void diagnostic(MXS_FILTER* instance, MXS_FILTER_SESSION* fsession, DCB* dcb);
|
return new(std::nothrow) HINT_SESSION(pSession);
|
||||||
static json_t* diagnostic_json(const MXS_FILTER* instance, const MXS_FILTER_SESSION* fsession);
|
}
|
||||||
static uint64_t getCapabilities(MXS_FILTER* instance);
|
|
||||||
|
void HINT_INSTANCE::diagnostics(DCB* pDcb) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
json_t* HINT_INSTANCE::diagnostics_json() const
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t HINT_INSTANCE::getCapabilities()
|
||||||
|
{
|
||||||
|
return RCAP_TYPE_CONTIGUOUS_INPUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
HINT_SESSION::HINT_SESSION(MXS_SESSION* session)
|
||||||
|
: mxs::FilterSession(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
|
||||||
|
*/
|
||||||
|
HINT_SESSION::~HINT_SESSION()
|
||||||
|
{
|
||||||
|
for (auto& a : named_hints)
|
||||||
|
{
|
||||||
|
hint_free(a.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& a : stack)
|
||||||
|
{
|
||||||
|
hint_free(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The routeQuery entry point. This is passed the query buffer
|
||||||
|
* to which the filter should be applied. Once applied the
|
||||||
|
* query should 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
|
||||||
|
*/
|
||||||
|
int HINT_SESSION::routeQuery(GWBUF* queue)
|
||||||
|
{
|
||||||
|
if (modutil_is_SQL(queue) && gwbuf_length(queue) > 5)
|
||||||
|
{
|
||||||
|
process_hints(queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mxs::FilterSession::routeQuery(queue);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -51,22 +109,6 @@ extern "C"
|
|||||||
*/
|
*/
|
||||||
MXS_MODULE* MXS_CREATE_MODULE()
|
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,
|
|
||||||
NULL, // No destroyInstance
|
|
||||||
};
|
|
||||||
|
|
||||||
static MXS_MODULE info =
|
static MXS_MODULE info =
|
||||||
{
|
{
|
||||||
MXS_MODULE_API_FILTER,
|
MXS_MODULE_API_FILTER,
|
||||||
@ -75,7 +117,7 @@ extern "C"
|
|||||||
"A hint parsing filter",
|
"A hint parsing filter",
|
||||||
"V1.0.0",
|
"V1.0.0",
|
||||||
RCAP_TYPE_CONTIGUOUS_INPUT,
|
RCAP_TYPE_CONTIGUOUS_INPUT,
|
||||||
&MyObject,
|
&HINT_INSTANCE::s_object,
|
||||||
NULL, /* Process init. */
|
NULL, /* Process init. */
|
||||||
NULL, /* Process finish. */
|
NULL, /* Process finish. */
|
||||||
NULL, /* Thread init. */
|
NULL, /* Thread init. */
|
||||||
@ -88,138 +130,3 @@ extern "C"
|
|||||||
return &info;
|
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, MXS_CONFIG_PARAMETER* params)
|
|
||||||
{
|
|
||||||
return static_cast<MXS_FILTER*>(new(std::nothrow) HINT_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)
|
|
||||||
{
|
|
||||||
return static_cast<MXS_FILTER_SESSION*>(new(std::nothrow) HINT_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)
|
|
||||||
{
|
|
||||||
HINT_SESSION* my_session = (HINT_SESSION*)session;
|
|
||||||
|
|
||||||
for (auto& a : my_session->named_hints)
|
|
||||||
{
|
|
||||||
hint_free(a.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& a : my_session->stack)
|
|
||||||
{
|
|
||||||
hint_free(a);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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)
|
|
||||||
{
|
|
||||||
delete 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)
|
|
||||||
{
|
|
||||||
HINT_SESSION* my_session = (HINT_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 should 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)
|
|
||||||
{
|
|
||||||
HINT_SESSION* my_session = (HINT_SESSION*)session;
|
|
||||||
|
|
||||||
if (modutil_is_SQL(queue) && gwbuf_length(queue) > 5)
|
|
||||||
{
|
|
||||||
my_session->process_hints(queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now process the request */
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Diagnostics routine
|
|
||||||
*
|
|
||||||
* @param instance The filter instance
|
|
||||||
* @param fsession Filter session, may be NULL
|
|
||||||
*/
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
@ -14,25 +14,36 @@
|
|||||||
|
|
||||||
#include <maxscale/ccdefs.hh>
|
#include <maxscale/ccdefs.hh>
|
||||||
#include <maxscale/hint.h>
|
#include <maxscale/hint.h>
|
||||||
|
#include <maxscale/filter.hh>
|
||||||
|
|
||||||
/**
|
class HINT_SESSION;
|
||||||
* The hint instance structure
|
|
||||||
*/
|
class HINT_INSTANCE : public mxs::Filter<HINT_INSTANCE, HINT_SESSION>
|
||||||
struct HINT_INSTANCE : public MXS_FILTER
|
|
||||||
{
|
{
|
||||||
int sessions = 0;
|
public:
|
||||||
|
static HINT_INSTANCE* create(const char* zName, MXS_CONFIG_PARAMETER* ppParams);
|
||||||
|
HINT_SESSION* newSession(MXS_SESSION* pSession);
|
||||||
|
void diagnostics(DCB* pDcb) const;
|
||||||
|
json_t* diagnostics_json() const;
|
||||||
|
uint64_t getCapabilities();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
class HINT_SESSION : public mxs::FilterSession
|
||||||
* A hint parser session structure
|
|
||||||
*/
|
|
||||||
struct HINT_SESSION : public MXS_FILTER_SESSION
|
|
||||||
{
|
{
|
||||||
MXS_DOWNSTREAM down;
|
public:
|
||||||
|
HINT_SESSION(MXS_SESSION* session);
|
||||||
|
~HINT_SESSION();
|
||||||
|
int routeQuery(GWBUF* queue);
|
||||||
|
|
||||||
|
private:
|
||||||
std::vector<HINT*> stack;
|
std::vector<HINT*> stack;
|
||||||
std::unordered_map<std::string, HINT*> named_hints;
|
std::unordered_map<std::string, HINT*> named_hints;
|
||||||
|
|
||||||
template<class InputIter>
|
template<class InputIter>
|
||||||
HINT* process_comment(InputIter it, InputIter end);
|
HINT* process_comment(InputIter it, InputIter end);
|
||||||
void process_hints(GWBUF* buffer);
|
void process_hints(GWBUF* buffer);
|
||||||
|
|
||||||
|
// Unit testing functions
|
||||||
|
friend void count_hints(const std::string& input, int num_expected);
|
||||||
|
friend void test_parse(const std::string& input, int expected_type);
|
||||||
};
|
};
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "../hintparser.cc"
|
#include "../hintparser.cc"
|
||||||
|
#include "../hintfilter.cc"
|
||||||
#include <maxbase/log.hh>
|
#include <maxbase/log.hh>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -71,7 +72,7 @@ void test(const std::string& input, std::initializer_list<std::string> expected)
|
|||||||
mxb_assert(rval);
|
mxb_assert(rval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HINT_SESSION session = {};
|
static HINT_SESSION session(nullptr);
|
||||||
|
|
||||||
void test_parse(const std::string& input, int expected_type)
|
void test_parse(const std::string& input, int expected_type)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user