MXS-591 Add filter for injecting comments
Comments specified in the cnf file will be injected as a comment before every sql statement.
This commit is contained in:
parent
69b19d1473
commit
de1f95028b
70
Documentation/Filters/Comment.md
Normal file
70
Documentation/Filters/Comment.md
Normal file
@ -0,0 +1,70 @@
|
||||
|
||||
# Comment Filter
|
||||
|
||||
## Overview
|
||||
|
||||
With the _comment_ filter it is possible to define comments that are
|
||||
injected before the actual statements. These comments appear as sql
|
||||
comments when they are received by the server.
|
||||
|
||||
```
|
||||
[MyComment]
|
||||
type=filter
|
||||
module=comment
|
||||
inject=Comment to be injected
|
||||
|
||||
[MyService]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
servers=server1
|
||||
user=myuser
|
||||
passwd=mypasswd
|
||||
filters=MyComment
|
||||
```
|
||||
|
||||
|
||||
## Filter Parameters
|
||||
|
||||
The Comment filter requires one mandatory parameter to be defined.
|
||||
|
||||
### `inject`
|
||||
|
||||
A parameter that contains the comment injected before the statements.
|
||||
There is also defined variable $IP that can be used to comment the
|
||||
IP address of the client in the injected comment.
|
||||
Variables must be written in all caps.
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1 - Inject IP address of the connected client into statements
|
||||
as comment.
|
||||
|
||||
You want to see the IP addresses of the clients with the server so you
|
||||
define filter to comment the into the statements they send.
|
||||
|
||||
|
||||
```
|
||||
[IPComment]
|
||||
type=filter
|
||||
module=comment
|
||||
inject=IP=$IP
|
||||
|
||||
[MyService]
|
||||
type=service
|
||||
router=readwritesplit
|
||||
servers=server1
|
||||
user=myuser
|
||||
passwd=mypasswd
|
||||
filters=IPComment
|
||||
```
|
||||
|
||||
In this example when MaxScale receives statement like:
|
||||
```
|
||||
SELECT user FROM people;
|
||||
```
|
||||
It would look like
|
||||
```
|
||||
/* IP=::ffff:127.0.0.1 */SELECT user FROM people;
|
||||
```
|
||||
when received by server.
|
@ -16,3 +16,4 @@ add_subdirectory(tee)
|
||||
add_subdirectory(throttlefilter)
|
||||
add_subdirectory(topfilter)
|
||||
add_subdirectory(tpmfilter)
|
||||
add_subdirectory(comment)
|
||||
|
4
server/modules/filter/comment/CMakeLists.txt
Normal file
4
server/modules/filter/comment/CMakeLists.txt
Normal file
@ -0,0 +1,4 @@
|
||||
add_library(comment SHARED commentfilter.cc commentfiltersession.cc)
|
||||
set_target_properties(comment PROPERTIES VERSION "1.0.0")
|
||||
install_module(comment core)
|
||||
|
91
server/modules/filter/comment/commentfilter.cc
Normal file
91
server/modules/filter/comment/commentfilter.cc
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// All log messages from this module are prefixed with this
|
||||
#define MXS_MODULE_NAME "commentfilter"
|
||||
|
||||
#include "commentfilter.hh"
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
const char CN_INJECT[] = "inject";
|
||||
|
||||
}
|
||||
|
||||
// This declares a module in MaxScale
|
||||
extern "C" MXS_MODULE* MXS_CREATE_MODULE()
|
||||
{
|
||||
static MXS_MODULE info =
|
||||
{
|
||||
MXS_MODULE_API_FILTER,
|
||||
MXS_MODULE_IN_DEVELOPMENT,
|
||||
MXS_FILTER_VERSION,
|
||||
"A comment filter that can inject comments in sql queries",
|
||||
"V1.0.0",
|
||||
RCAP_TYPE_NONE,
|
||||
&CommentFilter::s_object, // This is defined in the MaxScale filter template
|
||||
NULL, /* Process init. */
|
||||
NULL, /* Process finish. */
|
||||
NULL, /* Thread init. */
|
||||
NULL, /* Thread finish. */
|
||||
{
|
||||
{ CN_INJECT, MXS_MODULE_PARAM_STRING, NULL, MXS_MODULE_OPT_REQUIRED },
|
||||
{ MXS_END_MODULE_PARAMS }
|
||||
}
|
||||
};
|
||||
|
||||
return &info;
|
||||
}
|
||||
|
||||
CommentFilter::CommentFilter(std::string comment) : m_comment(comment)
|
||||
{
|
||||
MXS_INFO("Comment filter with comment [%s] created.", m_comment.c_str());
|
||||
}
|
||||
|
||||
CommentFilter::~CommentFilter()
|
||||
{
|
||||
}
|
||||
|
||||
// static
|
||||
CommentFilter* CommentFilter::create(const char* zName, char** pzOptions, MXS_CONFIG_PARAMETER* pParams)
|
||||
{
|
||||
return new CommentFilter(config_get_string(pParams, CN_INJECT));
|
||||
}
|
||||
|
||||
CommentFilterSession* CommentFilter::newSession(MXS_SESSION* pSession)
|
||||
{
|
||||
return CommentFilterSession::create(pSession, this);
|
||||
}
|
||||
|
||||
// static
|
||||
void CommentFilter::diagnostics(DCB* pDcb) const
|
||||
{
|
||||
dcb_printf(pDcb, "Comment filter with comment: %s", m_comment.c_str());
|
||||
}
|
||||
|
||||
// static
|
||||
json_t* CommentFilter::diagnostics_json() const
|
||||
{
|
||||
json_t* rval = json_object();
|
||||
json_object_set_new(rval, "Comment", json_string(m_comment.c_str()));
|
||||
return rval;
|
||||
}
|
||||
|
||||
// static
|
||||
uint64_t CommentFilter::getCapabilities()
|
||||
{
|
||||
return RCAP_TYPE_NONE;
|
||||
}
|
53
server/modules/filter/comment/commentfilter.hh
Normal file
53
server/modules/filter/comment/commentfilter.hh
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
/*
|
||||
* 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 <maxscale/cppdefs.hh>
|
||||
#include <maxscale/filter.hh>
|
||||
#include "commentfiltersession.hh"
|
||||
#include <string>
|
||||
|
||||
class CommentFilter : public maxscale::Filter<CommentFilter, CommentFilterSession>
|
||||
{
|
||||
public:
|
||||
// Prevent copy-constructor and assignment operator usage
|
||||
CommentFilter(const CommentFilter&) = delete;
|
||||
CommentFilter& operator = (const CommentFilter&) = delete;
|
||||
|
||||
~CommentFilter();
|
||||
|
||||
// Creates a new filter instance
|
||||
static CommentFilter* create(const char* zName, char** pzOptions, MXS_CONFIG_PARAMETER* ppParams);
|
||||
|
||||
// Creates a new session for this filter
|
||||
CommentFilterSession* newSession(MXS_SESSION* pSession);
|
||||
|
||||
// Print diagnostics to a DCB
|
||||
void diagnostics(DCB* pDcb) const;
|
||||
|
||||
|
||||
// Returns JSON form diagnostic data
|
||||
json_t* diagnostics_json() const;
|
||||
|
||||
// Get filter capabilities
|
||||
uint64_t getCapabilities();
|
||||
std::string comment() const
|
||||
{
|
||||
return m_comment;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_comment;
|
||||
// Used in the create function
|
||||
CommentFilter(std::string comment);
|
||||
};
|
80
server/modules/filter/comment/commentfiltersession.cc
Normal file
80
server/modules/filter/comment/commentfiltersession.cc
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// All log messages from this module are prefixed with this
|
||||
#define MXS_MODULE_NAME "commentfilter"
|
||||
|
||||
#include "commentfiltersession.hh"
|
||||
#include "commentfilter.hh"
|
||||
#include <maxscale/modutil.hh>
|
||||
#include <string>
|
||||
#include <regex>
|
||||
|
||||
using namespace std;
|
||||
|
||||
CommentFilterSession::CommentFilterSession(MXS_SESSION* pSession, const CommentFilter* pFilter)
|
||||
: maxscale::FilterSession(pSession),
|
||||
m_filter(*pFilter)
|
||||
{
|
||||
}
|
||||
|
||||
CommentFilterSession::~CommentFilterSession()
|
||||
{
|
||||
}
|
||||
|
||||
//static
|
||||
CommentFilterSession* CommentFilterSession::create(MXS_SESSION* pSession, const CommentFilter* pFilter)
|
||||
{
|
||||
return new CommentFilterSession(pSession, pFilter);
|
||||
}
|
||||
|
||||
void CommentFilterSession::close()
|
||||
{
|
||||
}
|
||||
|
||||
int CommentFilterSession::routeQuery(GWBUF* pPacket)
|
||||
{
|
||||
if (modutil_is_SQL(pPacket))
|
||||
{
|
||||
string sql = mxs::extract_sql(pPacket);
|
||||
string comment = parseComment(m_filter.comment());
|
||||
string newsql = string("/* ").append(comment).append(" */").append(sql);
|
||||
pPacket = modutil_replace_SQL(pPacket, (char*)newsql.c_str());
|
||||
//maxscale expects contiguous memory to arrive from client so we must make the buffer contiguous
|
||||
//after using modutil_replace_SQL.
|
||||
GWBUF* pModified_packet = gwbuf_make_contiguous(pPacket);
|
||||
if (pModified_packet)
|
||||
{
|
||||
pPacket = pModified_packet;
|
||||
}
|
||||
else
|
||||
{
|
||||
gwbuf_free(pPacket);
|
||||
pPacket = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return pPacket ? mxs::FilterSession::routeQuery(pPacket) : 1;
|
||||
}
|
||||
|
||||
int CommentFilterSession::clientReply(GWBUF* pPacket)
|
||||
{
|
||||
return mxs::FilterSession::clientReply(pPacket);
|
||||
}
|
||||
//TODO this probably should be refactored in some way in case we add more variables
|
||||
string CommentFilterSession::parseComment(string comment)
|
||||
{
|
||||
string ip = m_pSession->client_dcb->remote;
|
||||
string parsedComment = std::regex_replace(comment, std::regex("\\$IP"), ip);
|
||||
return parsedComment;
|
||||
}
|
48
server/modules/filter/comment/commentfiltersession.hh
Normal file
48
server/modules/filter/comment/commentfiltersession.hh
Normal file
@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
/*
|
||||
* 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 <maxscale/cppdefs.hh>
|
||||
#include <maxscale/filter.hh>
|
||||
#include <string>
|
||||
|
||||
class CommentFilter;
|
||||
|
||||
class CommentFilterSession : public maxscale::FilterSession
|
||||
{
|
||||
// Prevent copy-constructor and assignment operator usage
|
||||
CommentFilterSession(const CommentFilterSession&);
|
||||
CommentFilterSession& operator = (const CommentFilterSession&);
|
||||
|
||||
public:
|
||||
~CommentFilterSession();
|
||||
|
||||
// Called when a client session has been closed
|
||||
void close();
|
||||
|
||||
// Create a new filter session
|
||||
static CommentFilterSession* create(MXS_SESSION* pSession, const CommentFilter* pFilter);
|
||||
|
||||
// Handle a query from the client
|
||||
int routeQuery(GWBUF* pPacket);
|
||||
|
||||
// Handle a reply from server
|
||||
int clientReply(GWBUF* pPacket);
|
||||
|
||||
private:
|
||||
|
||||
// Used in the create function
|
||||
CommentFilterSession(MXS_SESSION* pSession, const CommentFilter* pFilter);
|
||||
const CommentFilter& m_filter;
|
||||
std::string parseComment(std::string comment);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user