[asterisk-commits] gtjoseph: trunk r428545 - in /trunk: ./ main/ res/ tests/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Nov 21 11:49:42 CST 2014
Author: gtjoseph
Date: Fri Nov 21 11:49:39 2014
New Revision: 428545
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=428545
Log:
sorcery: Make is_object_field_registered handle field names that are regexes.
As a result of https://reviewboard.asterisk.org/r/3305, res_sorcery_realtime
was tossing database fields that didn't have an exact match to a sorcery
registered field. This broke the ability to use regexes as field names which
manifested itself as a failure of res_pjsip_phoneprov_provider which uses
this capability. It also broke handling of fields that start with '@' in
realtime but I don't think anyone noticed.
This patch does the following...
* Modifies ast_sorcery_fields_register to pre-compile the name regex.
* Modifies ast_sorcery_is_object_field_registered to test the regex if it
exists instead of doing an exact strcmp.
* Modifies res_pjsip_phoneprov_provider with a few tweaks to get it to work
with realtime.
Tested-by: George Joseph
Review: https://reviewboard.asterisk.org/r/4185/
........
Merged revisions 428543 from http://svn.asterisk.org/svn/asterisk/branches/12
........
Merged revisions 428544 from http://svn.asterisk.org/svn/asterisk/branches/13
Modified:
trunk/ (props changed)
trunk/main/sorcery.c
trunk/res/res_pjsip_phoneprov_provider.c
trunk/tests/test_sorcery.c
Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-13-merged' - no diff available.
Modified: trunk/main/sorcery.c
URL: http://svnview.digium.com/svn/asterisk/trunk/main/sorcery.c?view=diff&rev=428545&r1=428544&r2=428545
==============================================================================
--- trunk/main/sorcery.c (original)
+++ trunk/main/sorcery.c Fri Nov 21 11:49:39 2014
@@ -140,6 +140,9 @@
/*! \brief Name of the field */
char name[MAX_OBJECT_FIELD];
+ /*! \brief The compiled name regex if name is a regex */
+ regex_t *name_regex;
+
/*! \brief Callback function for translation of a single value */
sorcery_field_handler handler;
@@ -869,17 +872,40 @@
object_type->diff = diff;
}
+static void sorcery_object_field_destructor(void *obj)
+{
+ struct ast_sorcery_object_field *object_field = obj;
+
+ if (object_field->name_regex) {
+ regfree(object_field->name_regex);
+ }
+}
+
int ast_sorcery_object_fields_register(struct ast_sorcery *sorcery, const char *type, const char *regex, aco_option_handler config_handler, sorcery_fields_handler sorcery_handler)
{
+#define MAX_REGEX_ERROR_LEN 128
RAII_VAR(struct ast_sorcery_object_type *, object_type, ao2_find(sorcery->types, type, OBJ_KEY), ao2_cleanup);
RAII_VAR(struct ast_sorcery_object_field *, object_field, NULL, ao2_cleanup);
-
- if (!object_type || !object_type->type.item_alloc || !config_handler || !(object_field = ao2_alloc(sizeof(*object_field), NULL))) {
+ int rc;
+
+ if (!object_type || !object_type->type.item_alloc || !config_handler
+ || !(object_field = ao2_alloc(sizeof(*object_field), sorcery_object_field_destructor))) {
return -1;
}
ast_copy_string(object_field->name, regex, sizeof(object_field->name));
object_field->multiple_handler = sorcery_handler;
+
+ if (!(object_field->name_regex = ast_calloc(1, sizeof(regex_t)))) {
+ return -1;
+ }
+
+ if ((rc = regcomp(object_field->name_regex, regex, REG_EXTENDED | REG_NOSUB))) {
+ char *regerr = ast_alloca(MAX_REGEX_ERROR_LEN);
+ regerror(rc, object_field->name_regex, regerr, MAX_REGEX_ERROR_LEN);
+ ast_log(LOG_ERROR, "Regular expression '%s' failed to compile: %s\n", regex, regerr);
+ return -1;
+ }
ao2_link(object_type->fields, object_field);
__aco_option_register(object_type->info, regex, ACO_REGEX, object_type->file->types, "", OPT_CUSTOM_T, config_handler, 0, 1, 0);
@@ -1926,6 +1952,20 @@
return ao2_find(sorcery->types, type, OBJ_SEARCH_KEY);
}
+static int is_registered_cb(void *obj, void *arg, int flags)
+{
+ struct ast_sorcery_object_field *object_field = obj;
+ char *name = arg;
+ int rc = 0;
+
+ if (object_field->name_regex
+ && !regexec(object_field->name_regex, name, 0, NULL, 0)) {
+ rc = CMP_MATCH | CMP_STOP;
+ }
+
+ return rc;
+}
+
int ast_sorcery_is_object_field_registered(const struct ast_sorcery_object_type *object_type,
const char *field_name)
{
@@ -1935,6 +1975,11 @@
ast_assert(object_type != NULL);
object_field = ao2_find(object_type->fields, field_name, OBJ_SEARCH_KEY);
+
+ if (!object_field) {
+ object_field = ao2_callback(object_type->fields, 0, is_registered_cb, (char *)field_name);
+ }
+
if (!object_field) {
res = 0;
}
Modified: trunk/res/res_pjsip_phoneprov_provider.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_pjsip_phoneprov_provider.c?view=diff&rev=428545&r1=428544&r2=428545
==============================================================================
--- trunk/res/res_pjsip_phoneprov_provider.c (original)
+++ trunk/res/res_pjsip_phoneprov_provider.c Fri Nov 21 11:49:39 2014
@@ -289,7 +289,7 @@
int user_count = 0;
char port_string[6];
- c = ast_sorcery_retrieve_by_regex(sorcery, "phoneprov", "");
+ c = ast_sorcery_retrieve_by_fields(sorcery, "phoneprov", AST_RETRIEVE_FLAG_MULTIPLE, NULL);
if (!c) {
ast_log(LOG_ERROR, "Retrieve by regex failed to allocate a container.\n");
return -1;
@@ -377,12 +377,7 @@
return AST_MODULE_LOAD_DECLINE;
}
- if (ast_sorcery_apply_default(sorcery, "phoneprov", "config",
- "pjsip.conf,criteria=type=phoneprov")) {
- ast_log(LOG_ERROR, "Unable to register object phoneprov.\n");
- ast_sorcery_unref(sorcery);
- return AST_MODULE_LOAD_DECLINE;
- }
+ ast_sorcery_apply_default(sorcery, "phoneprov", "config", "pjsip.conf,criteria=type=phoneprov");
ast_sorcery_object_register(sorcery, "phoneprov", phoneprov_alloc, NULL,
users_apply_handler);
Modified: trunk/tests/test_sorcery.c
URL: http://svnview.digium.com/svn/asterisk/trunk/tests/test_sorcery.c?view=diff&rev=428545&r1=428544&r2=428545
==============================================================================
--- trunk/tests/test_sorcery.c (original)
+++ trunk/tests/test_sorcery.c Fri Nov 21 11:49:39 2014
@@ -2991,6 +2991,48 @@
}
ast_free(buf);
+
+ return AST_TEST_PASS;
+}
+
+AST_TEST_DEFINE(object_field_registered)
+{
+ RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref);
+ RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup);
+
+ switch (cmd) {
+ case TEST_INIT:
+ info->name = "object_field_registered";
+ info->category = "/main/sorcery/";
+ info->summary = "ast_sorcery_is_object_field_registered unit test";
+ info->description =
+ "Test ast_sorcery_is_object_field_registered in sorcery";
+ return AST_TEST_NOT_RUN;
+ case TEST_EXECUTE:
+ break;
+ }
+
+ if (!(sorcery = alloc_and_initialize_sorcery())) {
+ ast_test_status_update(test, "Failed to open sorcery structure\n");
+ return AST_TEST_FAIL;
+ }
+
+ object_type = ast_sorcery_get_object_type(sorcery, "test");
+
+ ast_sorcery_object_fields_register(sorcery, "test", "^prefix/.", test_sorcery_regex_handler, test_sorcery_regex_fields);
+
+ ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "joe"));
+ ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "bob"));
+ ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "@joebob"));
+ ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "prefix/goober"));
+
+ ast_test_validate(test, !ast_sorcery_is_object_field_registered(object_type, "joebob"));
+ ast_test_validate(test, !ast_sorcery_is_object_field_registered(object_type, "prefix/"));
+ ast_test_validate(test, !ast_sorcery_is_object_field_registered(object_type, "goober"));
+
+ ast_sorcery_object_fields_register(sorcery, "test", "^", test_sorcery_regex_handler, test_sorcery_regex_fields);
+
+ ast_test_validate(test, ast_sorcery_is_object_field_registered(object_type, "goober"));
return AST_TEST_PASS;
}
@@ -3041,6 +3083,8 @@
AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_multiple);
AST_TEST_UNREGISTER(configuration_file_wizard_retrieve_multiple_all);
AST_TEST_UNREGISTER(dialplan_function);
+ AST_TEST_UNREGISTER(object_field_registered);
+
return 0;
}
@@ -3090,6 +3134,8 @@
AST_TEST_REGISTER(configuration_file_wizard_retrieve_multiple);
AST_TEST_REGISTER(configuration_file_wizard_retrieve_multiple_all);
AST_TEST_REGISTER(dialplan_function);
+ AST_TEST_REGISTER(object_field_registered);
+
return AST_MODULE_LOAD_SUCCESS;
}
More information about the asterisk-commits
mailing list