-I$(top_srcdir)/src/lib-mail \
-I$(top_srcdir)/src/lib-imap \
-I$(top_srcdir)/src/lib-index \
+ -I$(top_srcdir)/src/lib-settings \
-I$(top_srcdir)/src/lib-storage \
-I$(top_srcdir)/src/plugins/fts
lib21_fts_solr_plugin_la_SOURCES = \
fts-backend-solr.c \
fts-solr-plugin.c \
+ fts-solr-settings.c \
solr-response.c \
solr-connection.c
noinst_HEADERS = \
fts-solr-plugin.h \
+ fts-solr-settings.h \
solr-response.h \
solr-connection.h
*error_r = "Invalid fts_solr setting";
return -1;
}
- return solr_connection_init(&fuser->set, _backend->event,
+ return solr_connection_init(fuser->set, _backend->event,
&backend->solr_conn, error_r);
}
struct fts_solr_user *fuser =
FTS_SOLR_USER_CONTEXT_REQUIRE(ctx->ctx.backend->ns->user);
- if (!fuser->set.soft_commit)
+ if (!fuser->set->soft_commit)
return 0;
const char *str = t_strdup_printf(
struct fts_solr_user *fuser =
FTS_SOLR_USER_CONTEXT_REQUIRE(ctx->ctx.backend->ns->user);
- if (ctx->mails_since_flush >= fuser->set.batch_size) {
+ if (ctx->mails_since_flush >= fuser->set->batch_size) {
if (fts_backed_solr_build_flush(ctx) < 0)
ctx->ctx.failed = TRUE;
}
#include "solr-connection.h"
#include "fts-user.h"
#include "fts-solr-plugin.h"
-
-#define DEFAULT_SOLR_BATCH_SIZE 1000
+#include "settings.h"
+#include "fts-solr-settings.h"
const char *fts_solr_plugin_version = DOVECOT_ABI_VERSION;
struct http_client *solr_http_client = NULL;
struct fts_solr_user_module fts_solr_user_module =
MODULE_CONTEXT_INIT(&mail_user_module_register);
-static int
-fts_solr_plugin_init_settings(struct mail_user *user,
- struct fts_solr_settings *set, const char *str)
-{
- const char *value, *const *tmp;
-
- if (str == NULL)
- str = "";
-
- set->batch_size = DEFAULT_SOLR_BATCH_SIZE;
- set->soft_commit = TRUE;
-
- for (tmp = t_strsplit_spaces(str, " "); *tmp != NULL; tmp++) {
- if (str_begins(*tmp, "url=", &value)) {
- set->url = p_strdup(user->pool, value);
- } else if (strcmp(*tmp, "debug") == 0) {
- set->debug = TRUE;
- } else if (str_begins(*tmp, "rawlog_dir=", &value)) {
- set->rawlog_dir = p_strdup(user->pool, value);
- } else if (str_begins(*tmp, "batch_size=", &value)) {
- if (str_to_uint(value, &set->batch_size) < 0 ||
- set->batch_size == 0) {
- e_error(user->event,
- "fts-solr: batch_size must be a positive integer");
- return -1;
- }
- } else if (str_begins(*tmp, "soft_commit=", &value)) {
- if (strcmp(value, "yes") == 0) {
- set->soft_commit = TRUE;
- } else if (strcmp(value, "no") == 0) {
- set->soft_commit = FALSE;
- } else {
- e_error(user->event,
- "fts-solr: Invalid setting for soft_commit: %s",
- *tmp+12);
- return -1;
- }
- } else {
- e_error(user->event,
- "fts-solr: Invalid setting: %s", *tmp);
- return -1;
- }
- }
- if (set->url == NULL) {
- e_error(user->event, "fts-solr: url setting missing");
- return -1;
- }
- return 0;
-}
-
static void fts_solr_mail_user_deinit(struct mail_user *user)
{
struct fts_solr_user *fuser = FTS_SOLR_USER_CONTEXT_REQUIRE(user);
fts_mail_user_deinit(user);
+ settings_free(fuser->set);
fuser->module_ctx.super.deinit(user);
}
-static void fts_solr_mail_user_create(struct mail_user *user, const char *env)
+static void fts_solr_mail_user_created(struct mail_user *user)
{
struct mail_user_vfuncs *v = user->vlast;
struct fts_solr_user *fuser;
const char *error;
+ const struct fts_solr_settings *set;
- fuser = p_new(user->pool, struct fts_solr_user, 1);
- if (fts_solr_plugin_init_settings(user, &fuser->set, env) < 0) {
- /* invalid settings, disabling */
+ if (fts_solr_settings_get(user->event, &fts_solr_setting_parser_info,
+ &set, &error) < 0) {
+ e_error(user->event, "fts-solr: %s", error);
return;
}
+
if (fts_mail_user_init(user, FALSE, &error) < 0) {
e_error(user->event, "fts-solr: %s", error);
+ settings_free(set);
return;
}
+ fuser = p_new(user->pool, struct fts_solr_user, 1);
+ fuser->set = set;
fuser->module_ctx.super = *v;
user->vlast = &fuser->module_ctx.super;
v->deinit = fts_solr_mail_user_deinit;
MODULE_CONTEXT_SET(user, fts_solr_user_module, fuser);
}
-static void fts_solr_mail_user_created(struct mail_user *user)
-{
- const char *env;
-
- env = mail_user_plugin_getenv(user, "fts_solr");
- if (env != NULL)
- fts_solr_mail_user_create(user, env);
-}
-
static struct mail_storage_hooks fts_solr_mail_storage_hooks = {
.mail_user_created = fts_solr_mail_user_created
};
#include "module-context.h"
#include "mail-user.h"
#include "fts-api-private.h"
+#include "fts-solr-settings.h"
#define FTS_SOLR_USER_CONTEXT(obj) \
MODULE_CONTEXT(obj, fts_solr_user_module)
#define FTS_SOLR_USER_CONTEXT_REQUIRE(obj) \
MODULE_CONTEXT_REQUIRE(obj, fts_solr_user_module)
-struct fts_solr_settings {
- const char *url, *rawlog_dir;
- unsigned int batch_size;
- bool debug;
- bool soft_commit;
-};
-
struct fts_solr_user {
union mail_user_module_context module_ctx;
- struct fts_solr_settings set;
+ const struct fts_solr_settings *set;
};
extern const char *fts_solr_plugin_dependencies[];
--- /dev/null
+/* Copyright (c) 2023 Dovecot Oy, see the included COPYING file */
+
+#include "lib.h"
+#include "settings.h"
+#include "settings-parser.h"
+#include "fts-solr-settings.h"
+
+#undef DEF
+#define DEF(type, name) SETTING_DEFINE_STRUCT_##type( \
+ FTS_SOLR_FILTER"_"#name, name, struct fts_solr_settings)
+
+static const struct setting_define fts_solr_setting_defines[] = {
+ { .type = SET_FILTER_NAME, .key = FTS_SOLR_FILTER },
+ DEF(STR, url),
+ DEF(UINT, batch_size),
+ DEF(BOOL, soft_commit),
+ DEF(BOOL, debug),
+ SETTING_DEFINE_LIST_END
+};
+
+static const struct fts_solr_settings fts_solr_default_settings = {
+ .url = "",
+ .batch_size = 1000,
+ .soft_commit = TRUE,
+ .debug = FALSE,
+};
+
+static const struct setting_keyvalue fts_solr_default_settings_keyvalue[] = {
+ { FTS_SOLR_FILTER"/http_client_max_idle_time", "5s" },
+ { FTS_SOLR_FILTER"/http_client_max_parallel_connections", "1" },
+ { FTS_SOLR_FILTER"/http_client_max_pipelined_requests", "1" },
+ { FTS_SOLR_FILTER"/http_client_request_max_redirects", "1" },
+ { FTS_SOLR_FILTER"/http_client_request_max_attempts", "3" },
+ { FTS_SOLR_FILTER"/http_client_connect_timeout", "5s" },
+ { FTS_SOLR_FILTER"/http_client_request_timeout", "60s" },
+ { NULL, NULL }
+};
+
+const struct setting_parser_info fts_solr_setting_parser_info = {
+ .name = FTS_SOLR_FILTER,
+
+ .defines = fts_solr_setting_defines,
+ .defaults = &fts_solr_default_settings,
+ .default_settings = fts_solr_default_settings_keyvalue,
+
+ .struct_size = sizeof(struct fts_solr_settings),
+ .pool_offset1 = 1 + offsetof(struct fts_solr_settings, pool),
+};
+
+int fts_solr_settings_get(struct event *event,
+ const struct setting_parser_info *info,
+ const struct fts_solr_settings **set_r,
+ const char **error_r)
+{
+ if (settings_get(event, info, 0, set_r, error_r) < 0)
+ return -1;
+
+ const char *url = (*set_r)->url;
+ if (*url == '\0') {
+ *error_r = "fts_solr_url is required";
+ settings_free(*set_r);
+ return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+#ifndef FTS_SOLR_SETTINGS_H
+#define FTS_SOLR_SETTINGS_H
+
+/* <settings checks> */
+#define FTS_SOLR_FILTER "fts_solr"
+/* </settings checks> */
+
+struct fts_solr_settings {
+ pool_t pool;
+ const char *url;
+ unsigned int batch_size;
+ bool soft_commit;
+ bool debug;
+};
+
+extern const struct setting_parser_info fts_solr_setting_parser_info;
+int fts_solr_settings_get(struct event *event,
+ const struct setting_parser_info *info,
+ const struct fts_solr_settings **set,
+ const char **error_r);
+
+#endif
#include "istream.h"
#include "http-url.h"
#include "http-client.h"
+#include "settings.h"
#include "fts-solr-plugin.h"
#include "solr-connection.h"
struct event *event_parent,
struct solr_connection **conn_r, const char **error_r)
{
- struct http_client_settings *http_set;
struct solr_connection *conn;
struct http_url *http_url;
const char *error;
conn->debug = solr_set->debug;
if (solr_http_client == NULL) {
- pool_t http_pool = pool_alloconly_create("solr http settings",
- sizeof(*http_set));
- http_set = p_new(http_pool, struct http_client_settings, 1);
- http_client_settings_init(http_pool, http_set);
-
- http_set->max_idle_time_msecs = 5*1000;
- http_set->max_parallel_connections = 1;
- http_set->max_pipelined_requests = 1;
- http_set->request_max_redirects = 1;
- http_set->request_max_attempts = 3;
- http_set->connect_timeout_msecs = 5*1000;
- http_set->request_timeout_msecs = 60*1000;
- http_set->rawlog_dir = p_strdup(http_pool, solr_set->rawlog_dir);
-
/* FIXME: We should initialize a shared client instead. However,
this is currently not possible due to an obscure bug
in the blocking HTTP payload API, which causes
conflicts with other HTTP applications like FTS Tika.
Using a private client will provide a quick fix for
now. */
- solr_http_client = http_client_init_private(http_set, conn->event);
- pool_unref(&http_pool);
+
+ event_set_ptr(conn->event, SETTINGS_EVENT_FILTER_NAME, FTS_SOLR_FILTER);
+ if (http_client_init_private_auto(conn->event, &solr_http_client,
+ &error) < 0) {
+ *error_r = t_strdup(error);
+ return -1;
+ }
}
*conn_r = conn;