summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/ommongodb/Makefile.am4
-rw-r--r--plugins/ommongodb/ommongodb.c179
2 files changed, 175 insertions, 8 deletions
diff --git a/plugins/ommongodb/Makefile.am b/plugins/ommongodb/Makefile.am
index 3a05c435..8b13c254 100644
--- a/plugins/ommongodb/Makefile.am
+++ b/plugins/ommongodb/Makefile.am
@@ -1,7 +1,7 @@
pkglib_LTLIBRARIES = ommongodb.la
ommongodb_la_SOURCES = ommongodb.c
-ommongodb_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(LIBMONGO_CLIENT_CFLAGS)
+ommongodb_la_CPPFLAGS = $(RSRT_CFLAGS) $(PTHREADS_CFLAGS) $(LIBMONGO_CLIENT_CFLAGS) $(JSON_C_CFLAGS)
ommongodb_la_LDFLAGS = -module -avoid-version
-ommongodb_la_LIBADD = $(LIBMONGO_CLIENT_LIBS)
+ommongodb_la_LIBADD = $(LIBMONGO_CLIENT_LIBS) $(JSON_C_LIBS)
EXTRA_DIST =
diff --git a/plugins/ommongodb/ommongodb.c b/plugins/ommongodb/ommongodb.c
index a3848edb..9a7ca9f7 100644
--- a/plugins/ommongodb/ommongodb.c
+++ b/plugins/ommongodb/ommongodb.c
@@ -30,8 +30,12 @@
#include <errno.h>
#include <assert.h>
#include <signal.h>
+#include <stdint.h>
#include <time.h>
#include <mongo.h>
+#include <json/json.h>
+/* For struct json_object_iter, should not be necessary in future versions */
+#include <json/json_object_private.h>
#include "rsyslog.h"
#include "conf.h"
@@ -42,6 +46,7 @@
#include "datetime.h"
#include "errmsg.h"
#include "cfsysline.h"
+#include "unicode-helper.h"
MODULE_TYPE_OUTPUT
MODULE_TYPE_NOKEEP
@@ -54,6 +59,7 @@ DEFobjCurrIf(datetime)
typedef struct _instanceData {
mongo_sync_connection *conn;
+ struct json_tokener *json_tokener; /* only if (tplName != NULL) */
uchar *server;
int port;
uchar *db;
@@ -108,11 +114,14 @@ static void closeMongoDB(instanceData *pData)
BEGINfreeInstance
CODESTARTfreeInstance
closeMongoDB(pData);
+ if (pData->json_tokener != NULL)
+ json_tokener_free(pData->json_tokener);
free(pData->server);
free(pData->db);
free(pData->collection);
free(pData->uid);
free(pData->pwd);
+ free(pData->dbNcoll);
free(pData->tplName);
ENDfreeInstance
@@ -280,6 +289,165 @@ dbgprintf("ommongodb: secfrac is %d, precision %d\n", pMsg->tTIMESTAMP.secfrac,
return doc;
}
+static bson *BSONFromJSONArray(struct json_object *json);
+static bson *BSONFromJSONObject(struct json_object *json);
+
+/* Append a BSON variant of json to doc using name. Return TRUE on success */
+static gboolean
+BSONAppendJSONObject(bson *doc, const gchar *name, struct json_object *json)
+{
+ switch(json_object_get_type(json)) {
+ case json_type_boolean:
+ return bson_append_boolean(doc, name,
+ json_object_get_boolean(json));
+ case json_type_double:
+ return bson_append_double(doc, name,
+ json_object_get_double(json));
+ case json_type_int: {
+ int64_t i;
+
+ /* FIXME: the future version will have get_int64 */
+ i = json_object_get_int(json);
+ if (i >= INT32_MIN && i <= INT32_MAX)
+ return bson_append_int32(doc, name, i);
+ else
+ return bson_append_int64(doc, name, i);
+ }
+ case json_type_object: {
+ bson *sub;
+ gboolean ok;
+
+ sub = BSONFromJSONObject(json);
+ if (sub == NULL)
+ return FALSE;
+ ok = bson_append_document(doc, name, sub);
+ bson_free(sub);
+ return ok;
+ }
+ case json_type_array: {
+ bson *sub;
+ gboolean ok;
+
+ sub = BSONFromJSONArray(json);
+ if (sub == NULL)
+ return FALSE;
+ ok = bson_append_document(doc, name, sub);
+ bson_free(sub);
+ return ok;
+ }
+ case json_type_string:
+ return bson_append_string(doc, name,
+ json_object_get_string(json), -1);
+
+ default:
+ return FALSE;
+ }
+}
+
+/* Return a BSON variant of json, which must be a json_type_array */
+static bson *
+BSONFromJSONArray(struct json_object *json)
+{
+ /* Way more than necessary */
+ bson *doc = NULL;
+ size_t i, array_len;
+
+ doc = bson_new();
+ if(doc == NULL)
+ goto error;
+
+ array_len = json_object_array_length(json);
+ for (i = 0; i < array_len; i++) {
+ char buf[sizeof(size_t) * CHAR_BIT + 1];
+
+ if ((size_t)snprintf(buf, sizeof(buf), "%zu", i) >= sizeof(buf))
+ goto error;
+ if (BSONAppendJSONObject(doc, buf,
+ json_object_array_get_idx(json, i))
+ == FALSE)
+ goto error;
+ }
+
+ if(bson_finish(doc) == FALSE)
+ goto error;
+
+ return doc;
+
+error:
+ if(doc != NULL)
+ bson_free(doc);
+ return NULL;
+}
+
+/* Return a BSON variant of json, which must be a json_type_object */
+static bson *
+BSONFromJSONObject(struct json_object *json)
+{
+ bson *doc = NULL;
+ struct json_object_iter it;
+
+ doc = bson_new();
+ if(doc == NULL)
+ goto error;
+
+ json_object_object_foreachC(json, it) {
+ if (BSONAppendJSONObject(doc, it.key, it.val) == FALSE)
+ goto error;
+ }
+
+ if(bson_finish(doc) == FALSE)
+ goto error;
+
+ return doc;
+
+error:
+ if(doc != NULL)
+ bson_free(doc);
+ return NULL;
+}
+
+/* Return a BSON document based on user's JSON string. */
+static bson *
+BSONFromJSONString(instanceData *pData, const char *json_string)
+{
+ size_t json_string_len;
+ struct json_object *json;
+ bson *doc = NULL;
+ const char *error_message;
+
+ json_tokener_reset(pData->json_tokener);
+
+ json_string_len = strlen(json_string);
+ json = json_tokener_parse_ex(pData->json_tokener,
+ json_string, json_string_len);
+ error_message = NULL;
+ if(json == NULL) {
+ enum json_tokener_error err;
+
+ err = pData->json_tokener->err;
+ if(err != json_tokener_continue)
+ error_message = json_tokener_errors[err];
+ else
+ error_message = "Unterminated input";
+ } else if((size_t)pData->json_tokener->char_offset < json_string_len)
+ error_message = "Extra characters after JSON object";
+ else if(!json_object_is_type(json, json_type_object))
+ error_message = "JSON value is not an object";
+ if(error_message != NULL) {
+ /* FIXME: is dbgprintf() the correct way to report the error? */
+ dbgprintf("ommongodb: Error parsing JSON '%s': %s\n",
+ json_string, error_message);
+ goto done;
+ }
+
+ doc = BSONFromJSONObject(json);
+
+done:
+ if(json != NULL)
+ json_object_put(json);
+ return doc;
+}
+
BEGINtryResume
CODESTARTtryResume
if(pData->conn == NULL) {
@@ -297,6 +465,8 @@ CODESTARTdoAction
if(pData->tplName == NULL) {
doc = getDefaultBSON((msg_t*)ppString[0]);
+ } else {
+ doc = BSONFromJSONString(pData, (const char *)ppString[0]);
}
if(doc == NULL) {
dbgprintf("ommongodb: error creating BSON doc\n");
@@ -366,12 +536,9 @@ CODESTARTnewActInst
if(pData->tplName == NULL) {
CHKiRet(OMSRsetEntry(*ppOMSR, 0, NULL, OMSR_TPL_AS_MSG));
} else {
- errmsg.LogError(0, RS_RET_LEGA_ACT_NOT_SUPPORTED,
- "ommongodb: templates are not supported in this version");
- ABORT_FINALIZE(RS_RET_ERR);
- CHKiRet(OMSRsetEntry(*ppOMSR, 0,
- (uchar*) strdup((char*) pData->tplName),
- OMSR_TPL_AS_ARRAY));
+ CHKiRet(OMSRsetEntry(*ppOMSR, 0, ustrdup(pData->tplName),
+ OMSR_NO_RQD_TPL_OPTS));
+ CHKmalloc(pData->json_tokener = json_tokener_new());
}
if(pData->db == NULL)