Updated documentation for luafilter

Added more documentation to functions about how, when and with what parameters
the Lua functions are called with. Also adjusted the module version to experimental.
This commit is contained in:
Markus Makela
2015-11-11 21:03:28 +02:00
parent 1c74ca0ec7
commit 140d284eed

View File

@ -20,12 +20,26 @@
* @file luafilter.c * @file luafilter.c
* Lua Filter * Lua Filter
* *
* A filter that calls a set of Lua script functions. * * A filter that calls a set of functions in a Lua script.
* *
* This filter calls the createInstance, newSession, closeSession, routeQuery and clientReply functions in the Lua script. * The entry points for the Lua script expect the following signatures:
* Out of these functions the newSession, closeSession, routeQuery and clientReply functions are * * nil createInstance() - global script only
* In addition to being called with the service-specific global Lua state created during createInstance, the following functions * * nil newSession()
* are called with a Lua state bound to the client session: newSession, closeSession, routeQuery and clientReply * * nil closeSession()
* * (nil | bool | string) routeQuery(string)
* * nil clientReply()
* * string diagnostic() - global script only
*
* These functions, if found in the script, will be called whenever a call to the
* matching entry point is made.
*
* The details for each entry point are documented in the functions.
* @see createInstance, newSession, closeSession, routeQuery, clientReply, diagnostic
*
* The filter has two scripts, a global and a session script. If the global script
* is defined and valid, the matching entry point function in Lua will be called.
* The same holds true for session script apart from no calls to createInstance
* or diagnostic being made for the session script.
*/ */
#include <skygw_types.h> #include <skygw_types.h>
@ -42,7 +56,7 @@
MODULE_INFO info = { MODULE_INFO info = {
MODULE_API_FILTER, MODULE_API_FILTER,
MODULE_ALPHA_RELEASE, MODULE_EXPERIMENTAL,
FILTER_VERSION, FILTER_VERSION,
"Lua Filter" "Lua Filter"
}; };
@ -123,7 +137,7 @@ typedef struct
} LUA_INSTANCE; } LUA_INSTANCE;
/** /**
* The session structure for Firewall filter. * The session structure for Lua filter.
*/ */
typedef struct typedef struct
{ {
@ -142,11 +156,12 @@ void
ModuleInit(){ } ModuleInit(){ }
/** /**
* Create an instance of the filter for a particular service * Create a new instance of the Lua filter.
* within MaxScale.
*
* @param options The options for this filter
* *
* The global script will be loaded in this function and executed once on a global
* level before calling the createInstance function in the Lua script.
* @param options The options for this filter
* @param params Filter parameters
* @return The instance data for this new instance * @return The instance data for this new instance
*/ */
static FILTER * static FILTER *
@ -215,10 +230,15 @@ createInstance(char **options, FILTER_PARAMETER **params)
* Create a new session * Create a new session
* *
* This function is called for each new client session and it is used to initialize * This function is called for each new client session and it is used to initialize
* data used for the duration of the session. The main function of this function * data used for the duration of the session.
* for the luafilter is to load the session script and allow it to do its initialization.
* *
* Once the script is loaded and executed globally, * This function first loads the session script and executes in on a global level.
* After this, the newSession function in the Lua scripts is called.
*
* There is a single C function exported as a global variable for the session
* script named id_gen. The id_gen function returns an int which is unique for
* each the sessions for this service. This function is only accessible to the
* session level scripts.
* @param instance The filter instance data * @param instance The filter instance data
* @param session The session itself * @param session The session itself
* @return Session specific data for this session * @return Session specific data for this session
@ -283,6 +303,7 @@ newSession(FILTER *instance, SESSION *session)
* Close a session with the filter, this is the mechanism * Close a session with the filter, this is the mechanism
* by which a filter may cleanup data structure etc. * by which a filter may cleanup data structure etc.
* *
* The closeSession function in the Lua scripts will be called.
* @param instance The filter instance data * @param instance The filter instance data
* @param session The session being closed * @param session The session being closed
*/ */
@ -355,6 +376,15 @@ setUpstream(FILTER *instance, void *session, UPSTREAM *upstream)
my_session->up = *upstream; my_session->up = *upstream;
} }
/**
* The client reply entry point.
*
* This function calls the clientReply function of the Lua scripts.
* @param instance Filter instance
* @param session Filter session
* @param queue Server response
* @return 1 on success
*/
static int static int
clientReply(FILTER *instance, void *session, GWBUF *queue) clientReply(FILTER *instance, void *session, GWBUF *queue)
{ {
@ -401,11 +431,13 @@ clientReply(FILTER *instance, void *session, GWBUF *queue)
* query is passed to the downstream component * query is passed to the downstream component
* (filter or router) in the filter chain. * (filter or router) in the filter chain.
* *
* The Luafilter calls the session specific and global Lua state object's routeQuery functions. * The Luafilter calls the routeQuery functions of both the session and the global script.
* The query is passed as a string parameter to the routeQuery Lua function and the return values of the session specific function, * The query is passed as a string parameter to the routeQuery Lua function and
* if any were returned, are interpreted. If the first value is a boolean, it is interpreted as a decision whether to pass the query onwards or * the return values of the session specific function, if any were returned,
* to send an error packet to the client. If it is a string, the current query is replaced with the return value. If no value is returned * are interpreted. If the first value is bool, it is interpreted as a decision
* or nil is returned, the query is passed on normally downstream to the next filter or router in the chain. * whether to route the query or to send an error packet to the client.
* If it is a string, the current query is replaced with the return value and
* the query will be routed. If nil is returned, the query is routed normally.
* *
* @param instance The filter instance data * @param instance The filter instance data
* @param session The filter session * @param session The filter session
@ -418,7 +450,6 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
LUA_INSTANCE *my_instance = (LUA_INSTANCE *) instance; LUA_INSTANCE *my_instance = (LUA_INSTANCE *) instance;
DCB* dcb = my_session->session->client; DCB* dcb = my_session->session->client;
char *fullquery = NULL, *ptr; char *fullquery = NULL, *ptr;
int qlen;
bool route = true; bool route = true;
GWBUF* forward = queue; GWBUF* forward = queue;
int rc = 0; int rc = 0;
@ -443,6 +474,10 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
{ {
if (lua_isstring(my_session->state, -1)) if (lua_isstring(my_session->state, -1))
{ {
if (forward)
{
gwbuf_free(forward);
}
forward = modutil_create_query((char*) lua_tostring(my_session->state, -1)); forward = modutil_create_query((char*) lua_tostring(my_session->state, -1));
} }
else if (lua_isboolean(my_session->state, -1)) else if (lua_isboolean(my_session->state, -1))
@ -464,6 +499,22 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
" to 'routeQuery' failed: '%s'.", " to 'routeQuery' failed: '%s'.",
lua_tostring(my_session->state, -1)); lua_tostring(my_session->state, -1));
} }
if (lua_gettop(my_instance->global_state))
{
if (lua_isstring(my_instance->global_state, -1))
{
if (forward)
{
gwbuf_free(forward);
}
forward = modutil_create_query((char*)
lua_tostring(my_instance->global_state, -1));
}
else if (lua_isboolean(my_instance->global_state, -1))
{
route = lua_toboolean(my_instance->global_state, -1);
}
}
spinlock_release(&my_instance->lock); spinlock_release(&my_instance->lock);
} }
@ -486,9 +537,10 @@ routeQuery(FILTER *instance, void *session, GWBUF *queue)
} }
/** /**
* Diagnostics routine * Diagnostics routine.
*, *
lua_tostring(my_instance->global_state, -1) * This will call the matching diagnostics entry point in the Lua script. If the
* Lua function returns a string, it will be printed to the client DCB.
* @param instance The filter instance * @param instance The filter instance
* @param fsession Filter session, may be NULL * @param fsession Filter session, may be NULL
* @param dcb The DCB for diagnostic output * @param dcb The DCB for diagnostic output