[asterisk-commits] kharwell: branch kharwell/stasis-http-conf r383651 - in /team/kharwell/stasis...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Mar 22 17:02:44 CDT 2013


Author: kharwell
Date: Fri Mar 22 17:02:42 2013
New Revision: 383651

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383651
Log:
Adding configuration options to stasis-http

Modified:
    team/kharwell/stasis-http-conf/include/asterisk/json.h
    team/kharwell/stasis-http-conf/res/res_json.c
    team/kharwell/stasis-http-conf/res/res_stasis_http.c
    team/kharwell/stasis-http-conf/res/res_stasis_websocket.c
    team/kharwell/stasis-http-conf/tests/test_json.c

Modified: team/kharwell/stasis-http-conf/include/asterisk/json.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/stasis-http-conf/include/asterisk/json.h?view=diff&rev=383651&r1=383650&r2=383651
==============================================================================
--- team/kharwell/stasis-http-conf/include/asterisk/json.h (original)
+++ team/kharwell/stasis-http-conf/include/asterisk/json.h Fri Mar 22 17:02:42 2013
@@ -581,16 +581,29 @@
 /*!@{*/
 
 /*!
+ * \brief Encoding format type.
+ * \since 12.0.0
+ */
+enum ast_json_encoding_format
+{
+	/*! Formatted for human readability */
+	AST_JSON_PRETTY = -1,
+	/*! Compact format, low human readability */
+	AST_JSON_COMPACT,
+};
+
+/*!
  * \brief Encode a JSON value to a string.
  * \since 12.0.0
  *
  * Returned string must be freed by calling ast_free().
  *
- * \param JSON value.
+ * \param root JSON value.
+ * \param format encoding format format.
  * \return String encoding of \a root.
  * \return \c NULL on error.
  */
-char *ast_json_dump_string(struct ast_json *root);
+char *ast_json_dump_string(struct ast_json *root, enum ast_json_encoding_format format);
 
 /*!
  * \brief Encode a JSON value to an \ref ast_str.
@@ -600,10 +613,11 @@
  *
  * \param root JSON value.
  * \param dst \ref ast_str to store JSON encoding.
+ * \param format encoding format format.
  * \return 0 on success.
  * \return -1 on error. The contents of \a dst are undefined.
  */
-int ast_json_dump_str(struct ast_json *root, struct ast_str **dst);
+int ast_json_dump_str(struct ast_json *root, struct ast_str **dst, enum ast_json_encoding_format format);
 
 /*!
  * \brief Encode a JSON value to a \c FILE.
@@ -611,10 +625,11 @@
  *
  * \param root JSON value.
  * \param output File to write JSON encoding to.
+ * \param format encoding format format.
  * \return 0 on success.
  * \return -1 on error. The contents of \a output are undefined.
  */
-int ast_json_dump_file(struct ast_json *root, FILE *output);
+int ast_json_dump_file(struct ast_json *root, FILE *output, enum ast_json_encoding_format format);
 
 /*!
  * \brief Encode a JSON value to a file at the given location.
@@ -622,10 +637,11 @@
  *
  * \param root JSON value.
  * \param path Path to file to write JSON encoding to.
+ * \param format encoding format format.
  * \return 0 on success.
  * \return -1 on error. The contents of \a output are undefined.
  */
-int ast_json_dump_new_file(struct ast_json *root, const char *path);
+int ast_json_dump_new_file(struct ast_json *root, const char *path, enum ast_json_encoding_format format);
 
 #define AST_JSON_ERROR_TEXT_LENGTH    160
 #define AST_JSON_ERROR_SOURCE_LENGTH   80

Modified: team/kharwell/stasis-http-conf/res/res_json.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/stasis-http-conf/res/res_json.c?view=diff&rev=383651&r1=383650&r2=383651
==============================================================================
--- team/kharwell/stasis-http-conf/res/res_json.c (original)
+++ team/kharwell/stasis-http-conf/res/res_json.c Fri Mar 22 17:02:42 2013
@@ -338,20 +338,15 @@
 /*!
  * \brief Default flags for JSON encoding.
  */
-static size_t dump_flags(void)
-{
-	/* There's a chance this could become a runtime flag */
-	int flags = JSON_COMPACT;
-#ifdef AST_DEVMODE
-	/* In dev mode, write readable JSON */
-	flags = JSON_INDENT(2) | JSON_PRESERVE_ORDER;
-#endif
-	return flags;
-}
-
-char *ast_json_dump_string(struct ast_json *root)
-{
-	return json_dumps((json_t *)root, dump_flags());
+static size_t dump_flags(enum ast_json_encoding_format format)
+{
+	return format == AST_JSON_PRETTY ?
+		JSON_INDENT(2) | JSON_PRESERVE_ORDER : JSON_COMPACT;
+}
+
+char *ast_json_dump_string(struct ast_json *root, enum ast_json_encoding_format format)
+{
+	return json_dumps((json_t *)root, dump_flags(format));
 }
 
 static int write_to_ast_str(const char *buffer, size_t size, void *data)
@@ -385,25 +380,25 @@
 	return 0;
 }
 
-int ast_json_dump_str(struct ast_json *root, struct ast_str **dst)
-{
-	return json_dump_callback((json_t *)root, write_to_ast_str, dst, dump_flags());
-}
-
-
-int ast_json_dump_file(struct ast_json *root, FILE *output)
+int ast_json_dump_str(struct ast_json *root, struct ast_str **dst, enum ast_json_encoding_format format)
+{
+	return json_dump_callback((json_t *)root, write_to_ast_str, dst, dump_flags(format));
+}
+
+
+int ast_json_dump_file(struct ast_json *root, FILE *output, enum ast_json_encoding_format format)
 {
 	if (!root || !output) {
 		return -1;
 	}
-	return json_dumpf((json_t *)root, output, dump_flags());
-}
-int ast_json_dump_new_file(struct ast_json *root, const char *path)
+	return json_dumpf((json_t *)root, output, dump_flags(format));
+}
+int ast_json_dump_new_file(struct ast_json *root, const char *path, enum ast_json_encoding_format format)
 {
 	if (!root || !path) {
 		return -1;
 	}
-	return json_dump_file((json_t *)root, path, dump_flags());
+	return json_dump_file((json_t *)root, path, dump_flags(format));
 }
 
 /*!

Modified: team/kharwell/stasis-http-conf/res/res_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/stasis-http-conf/res/res_stasis_http.c?view=diff&rev=383651&r1=383650&r2=383651
==============================================================================
--- team/kharwell/stasis-http-conf/res/res_stasis_http.c (original)
+++ team/kharwell/stasis-http-conf/res/res_stasis_http.c Fri Mar 22 17:02:42 2013
@@ -71,6 +71,23 @@
 	<support_level>core</support_level>
  ***/
 
+/*** DOCUMENTATION
+	<configInfo name="res_stasis_http" language="en_US">
+		<synopsis>HTTP binding for the Stasis API</synopsis>
+		<configFile name="stasis_http.conf">
+			<configObject name="global">
+				<synopsis>Global configuration settings</synopsis>
+				<configOption name="enabled">
+					<synopsis>Enable/disable the stasis-http module</synopsis>
+				</configOption>
+				<configOption name="pretty">
+					<synopsis>Responses from stasis-http are formatted to be human readable</synopsis>
+				</configOption>
+			</configObject>
+		</configFile>
+	</configInfo>
+***/
+
 #include "asterisk.h"
 
 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
@@ -78,10 +95,99 @@
 #include "asterisk/module.h"
 #include "asterisk/paths.h"
 #include "asterisk/stasis_http.h"
+#include "asterisk/config_options.h"
 
 #include <string.h>
 #include <sys/stat.h>
 #include <unistd.h>
+
+/*! \brief Global configuration options for stasis http. */
+struct conf_global_options {
+	/*! Enabled by default, disabled if false. */
+	int enabled:1;
+	/*! If true format the output to be human readable (default false). */
+	int pretty:1;
+};
+
+/*! \brief All configuration options for stasis http. */
+struct conf {
+	/*! The general section configuration options. */
+	struct conf_global_options *global;
+};
+
+/*! \brief Locking container for safe configuration access. */
+static AO2_GLOBAL_OBJ_STATIC(confs);
+
+/*! \brief Mapping of the stasis http conf struct's globals to the
+ *         general context in the config file. */
+static struct aco_type global_option = {
+	.type = ACO_GLOBAL,
+	.name = "global",
+	.item_offset = offsetof(struct conf, global),
+	.category = "^general$",
+	.category_match = ACO_WHITELIST
+};
+
+static struct aco_type *global_options[] = ACO_TYPES(&global_option);
+
+/*! \brief Disposes of the stasis http conf object */
+static void conf_destructor(void *obj)
+{
+    struct conf *cfg = obj;
+    ao2_cleanup(cfg->global);
+}
+
+/*! \brief Creates the statis http conf object. */
+static void *conf_alloc(void)
+{
+    struct conf *cfg;
+ 
+    if (!(cfg = ao2_alloc(sizeof(*cfg), conf_destructor))) {
+        return NULL;
+    }
+
+    if (!(cfg->global = ao2_alloc(sizeof(*cfg->global), NULL))) {
+        ao2_ref(cfg, -1);
+        return NULL;
+    }
+ 
+    return cfg;
+}
+ 
+/*! \brief The conf file that's processed for the module. */
+static struct aco_file conf_file = {
+	/*! The config file name. */
+	.filename = "stasis_http.conf",
+	/*! The mapping object types to be processed. */
+	.types = ACO_TYPES(&global_option),
+};
+
+CONFIG_INFO_STANDARD(cfg_info, confs, conf_alloc,
+		     .files = ACO_FILES(&conf_file));
+
+/*! \brief Bitfield handler since it is not possible to take address. */
+static int conf_bitfield_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+	struct conf_global_options *global = obj;
+
+	if (!strcasecmp(var->name, "enabled")) {
+		global->enabled = ast_true(var->value);
+	} else if (!strcasecmp(var->name, "pretty")) {
+		global->pretty = ast_true(var->value);
+	} else {
+		return -1;
+	}
+
+	return 0;
+}
+
+/*! \brief Helper function to check if module is enabled. */
+static char is_enabled(void)
+{
+	RAII_VAR(struct conf *, cfg, ao2_global_obj_ref(confs), ao2_cleanup);
+
+	return cfg->global->enabled;
+}
 
 /*! Handler for root RESTful resource. */
 static struct stasis_rest_handlers *root_handler;
@@ -572,6 +678,7 @@
 				struct ast_variable *get_params,
 				struct ast_variable *headers)
 {
+	RAII_VAR(struct conf *, cfg, ao2_global_obj_ref(confs), ao2_cleanup);
 	RAII_VAR(struct ast_str *, response_headers, ast_str_create(40), ast_free);
 	RAII_VAR(struct ast_str *, response_body, ast_str_create(256), ast_free);
 	struct stasis_http_response response = {};
@@ -618,7 +725,7 @@
 	if (response.message && !ast_json_is_null(response.message)) {
 		ast_str_append(&response_headers, 0,
 			       "Content-type: application/json\r\n");
-		if (ast_json_dump_str(response.message, &response_body) != 0) {
+		if (ast_json_dump_str(response.message, &response_body, cfg->global->pretty) != 0) {
 			/* Error encoding response */
 			response.response_code = 500;
 			response.response_text = "Internal Server Error";
@@ -659,29 +766,69 @@
 
 static int load_module(void)
 {
-	int r = 0;
+	if (aco_info_init(&cfg_info)) {
+		aco_info_destroy(&cfg_info);
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	aco_option_register_custom(&cfg_info, "enabled", ACO_EXACT, global_options,
+				   "yes", conf_bitfield_handler, 0);
+	aco_option_register_custom(&cfg_info, "pretty", ACO_EXACT, global_options,
+				   "no",  conf_bitfield_handler, 0);
+
+	if (aco_process_config(&cfg_info, 0)) {
+		aco_info_destroy(&cfg_info);
+		return AST_MODULE_LOAD_DECLINE;
+	}
 
 	alloc_failed_message = ast_json_pack("{s: s}",
 					     "message", "Allocation failed");
 
 	stasis_set_root_handler(stasis_default_root_handler());
-	r |= ast_http_uri_link(&http_uri);
-	return r;
+
+	if (is_enabled()) {
+		ast_http_uri_link(&http_uri);
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	int r = 0;
-
 	ast_json_unref(alloc_failed_message);
 	alloc_failed_message = NULL;
-	ast_http_uri_unlink(&http_uri);
-	return r;
+
+	if (is_enabled()) {
+		ast_http_uri_unlink(&http_uri);
+	}
+
+	aco_info_destroy(&cfg_info);
+	ao2_global_obj_release(confs);
+
+	return 0;
+}
+
+static int reload_module(void)
+{
+	char was_enabled = is_enabled();
+
+	if (aco_process_config(&cfg_info, 1)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	if (was_enabled && !is_enabled()) {
+		ast_http_uri_unlink(&http_uri);
+	} else if (!was_enabled && is_enabled()) {
+		ast_http_uri_link(&http_uri);
+	}
+
+	return AST_MODULE_LOAD_SUCCESS;
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,
 		"Stasis HTTP bindings",
 		.load = load_module,
 		.unload = unload_module,
+		.reload = reload_module,
 		.nonoptreq = "app_stasis,res_json"
 	);

Modified: team/kharwell/stasis-http-conf/res/res_stasis_websocket.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/stasis-http-conf/res/res_stasis_websocket.c?view=diff&rev=383651&r1=383650&r2=383651
==============================================================================
--- team/kharwell/stasis-http-conf/res/res_stasis_websocket.c (original)
+++ team/kharwell/stasis-http-conf/res/res_stasis_websocket.c Fri Mar 22 17:02:42 2013
@@ -93,7 +93,7 @@
  */
 static int ast_websocket_write_json(struct ast_websocket *session, struct ast_json *message)
 {
-	RAII_VAR(char *, str, ast_json_dump_string(message), ast_free);
+	RAII_VAR(char *, str, ast_json_dump_string(message, AST_JSON_COMPACT), ast_free);
 
 	if (str == NULL) {
 		ast_log(LOG_ERROR, "Failed to encode JSON object\n");

Modified: team/kharwell/stasis-http-conf/tests/test_json.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/stasis-http-conf/tests/test_json.c?view=diff&rev=383651&r1=383650&r2=383651
==============================================================================
--- team/kharwell/stasis-http-conf/tests/test_json.c (original)
+++ team/kharwell/stasis-http-conf/tests/test_json.c Fri Mar 22 17:02:42 2013
@@ -1133,14 +1133,14 @@
 		break;
 	}
 	expected = ast_json_pack("{ s: i }", "one", 1);
-	str = ast_json_dump_string(expected);
+	str = ast_json_dump_string(expected, AST_JSON_COMPACT);
 	ast_test_validate(test, NULL != str);
 	uut = ast_json_load_string(str, NULL);
 	ast_test_validate(test, NULL != uut);
 	ast_test_validate(test, ast_json_equal(expected, uut));
 
 	/* dump_string NULL */
-	ast_test_validate(test, NULL == ast_json_dump_string(NULL));
+	ast_test_validate(test, NULL == ast_json_dump_string(NULL, AST_JSON_COMPACT));
 
 	return AST_TEST_PASS;
 }
@@ -1167,7 +1167,7 @@
 	/* dump/load ast_str */
 	expected = ast_json_pack("{ s: i }", "one", 1);
 	astr = ast_str_create(1); /* should expand to hold output */
-	uut_res = ast_json_dump_str(expected, &astr);
+	uut_res = ast_json_dump_str(expected, &astr, AST_JSON_COMPACT);
 	ast_test_validate(test, 0 == uut_res);
 	uut = ast_json_load_str(astr, NULL);
 	ast_test_validate(test, NULL != uut);
@@ -1198,7 +1198,7 @@
 	/* dump ast_str growth failure */
 	expected = ast_json_pack("{ s: i }", "one", 1);
 	astr = ast_str_alloca(1); /* cannot grow */
-	uut_res = ast_json_dump_str(expected, &astr);
+	uut_res = ast_json_dump_str(expected, &astr, AST_JSON_COMPACT);
 	ast_test_validate(test, 0 != uut_res);
 
 	return AST_TEST_PASS;
@@ -1264,7 +1264,7 @@
 	expected = ast_json_pack("{ s: i }", "one", 1);
 	filename = tempnam(NULL, "ast-json");
 	file = fopen(filename, "w");
-	uut_res = ast_json_dump_file(expected, file);
+	uut_res = ast_json_dump_file(expected, file, AST_JSON_COMPACT);
 	ast_test_validate(test, 0 == uut_res);
 	fclose(file);
 	file = fopen(filename, "r");
@@ -1296,7 +1296,7 @@
 	/* dump/load filename */
 	expected = ast_json_pack("{ s: i }", "one", 1);
 	filename = tempnam(NULL, "ast-json");
-	uut_res = ast_json_dump_new_file(expected, filename);
+	uut_res = ast_json_dump_new_file(expected, filename, AST_JSON_COMPACT);
 	ast_test_validate(test, 0 == uut_res);
 	uut = ast_json_load_new_file(filename, NULL);
 	ast_test_validate(test, ast_json_equal(expected, uut));
@@ -1327,13 +1327,13 @@
 	ast_test_validate(test, NULL != uut);
 	filename = tempnam(NULL, "ast-json");
 	file = fopen(filename, "w");
-	ast_test_validate(test, NULL == ast_json_dump_string(NULL));
-	ast_test_validate(test, -1 == ast_json_dump_file(NULL, file));
-	ast_test_validate(test, -1 == ast_json_dump_file(uut, NULL));
-	ast_test_validate(test, -1 == ast_json_dump_file(NULL, NULL));
-	ast_test_validate(test, -1 == ast_json_dump_new_file(uut, NULL));
-	ast_test_validate(test, -1 == ast_json_dump_new_file(NULL, filename));
-	ast_test_validate(test, -1 == ast_json_dump_new_file(NULL, NULL));
+	ast_test_validate(test, NULL == ast_json_dump_string(NULL, AST_JSON_COMPACT));
+	ast_test_validate(test, -1 == ast_json_dump_file(NULL, file, AST_JSON_COMPACT));
+	ast_test_validate(test, -1 == ast_json_dump_file(uut, NULL, AST_JSON_COMPACT));
+	ast_test_validate(test, -1 == ast_json_dump_file(NULL, NULL, AST_JSON_COMPACT));
+	ast_test_validate(test, -1 == ast_json_dump_new_file(uut, NULL, AST_JSON_COMPACT));
+	ast_test_validate(test, -1 == ast_json_dump_new_file(NULL, filename, AST_JSON_COMPACT));
+	ast_test_validate(test, -1 == ast_json_dump_new_file(NULL, NULL, AST_JSON_COMPACT));
 	ast_test_validate(test, NULL == ast_json_load_string(NULL, NULL));
 	ast_test_validate(test, NULL == ast_json_load_buf(NULL, 0, NULL));
 	ast_test_validate(test, NULL == ast_json_load_file(NULL, NULL));
@@ -1604,7 +1604,7 @@
 	ast_test_validate(test, 0 == uut_res);
 	uut_res = ast_json_object_set(inner_child, "parent", ast_json_ref(uut));   /* incref to keep a reference */
 	ast_test_validate(test, 0 == uut_res);
-	str = ast_json_dump_string(uut);
+	str = ast_json_dump_string(uut, AST_JSON_COMPACT);
 	ast_test_validate(test, NULL == str);
 	/* Circular refs screw up reference counting, so break the cycle */
 	ast_json_object_clear(inner_child);




More information about the asterisk-commits mailing list