[asterisk-commits] mjordan: branch mjordan/trunk-astdb-cluster r433003 - in /team/mjordan/trunk-...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Mar 16 21:18:38 CDT 2015
Author: mjordan
Date: Mon Mar 16 21:18:35 2015
New Revision: 433003
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=433003
Log:
Update with pre-review findings
Modified:
team/mjordan/trunk-astdb-cluster/CHANGES
team/mjordan/trunk-astdb-cluster/configs/samples/pjsip.conf.sample
team/mjordan/trunk-astdb-cluster/funcs/func_db.c
team/mjordan/trunk-astdb-cluster/include/asterisk/astdb.h
team/mjordan/trunk-astdb-cluster/include/asterisk/event_defs.h
team/mjordan/trunk-astdb-cluster/main/db.c
team/mjordan/trunk-astdb-cluster/res/res_pjsip_publish_asterisk.c
team/mjordan/trunk-astdb-cluster/tests/test_db.c
Modified: team/mjordan/trunk-astdb-cluster/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk-astdb-cluster/CHANGES?view=diff&rev=433003&r1=433002&r2=433003
==============================================================================
--- team/mjordan/trunk-astdb-cluster/CHANGES (original)
+++ team/mjordan/trunk-astdb-cluster/CHANGES Mon Mar 16 21:18:35 2015
@@ -79,6 +79,28 @@
dedicated thread per consumer in certain cases. The initial settings for
the thread pool can now be configured in 'stasis.conf'.
+ * The AstDB now has the ability to share families of key/value pairs with
+ other Asterisk servers. Families in the AstDB can be marked as shared using
+ dialplan functions (which can be accessed via AMI, AGI, and ARI) or CLI
+ commands. Sharing has two strategies: 'global' and 'unique'. Global shared
+ families have a common family name across all Asterisk servers, and any
+ update to a key in that shared family is reflected in the same family across
+ other servers. Unique shared families are distributes to other Asterisk servers,
+ but are placed in a new family that corresponds to the remote instance's
+ EID. Currently, the PJSIP stack is the only mechanism available to share
+ AstDB families. See CLI updates, DB_SHARED/DB_SHARED_EXISTS, and the
+ res_pjsip updates for more information.
+
+CLI
+------------------
+ * The 'database show' and 'database showkey' commands have been updated
+ to display the shared status of the family the key(s) reside in a new
+ column. A value of '(G)' indicates the key is shared 'globally', a value
+ of '(U)' indicates the key is shared 'uniquely'.
+
+ * Added commands 'database put shared' and 'database del shared'. These
+ commands add/delete the shared status of AstDB families, respectively.
+
Functions
------------------
@@ -87,6 +109,15 @@
------------------
* Added CHANNEL(onhold) item that returns 1 (onhold) and 0 (not-onhold) for
the hold status of a channel.
+
+DB_SHARED
+------------------
+ * A new function, this will either create a new shared family in the AstDB
+ or delete an existing shared family.
+
+DB_SHARED_EXISTS
+------------------
+ * Determines whether an AstDB family is shared.
DTMF Features
------------------
@@ -105,6 +136,13 @@
* Added preferchannelclass=no option to prefer the application-passed class
over the channel-set musicclass. This allows separate hold-music from
application (e.g. Queue or Dial) specified music.
+
+res_pjsip_publish_asterisk
+------------------
+ * Added the ability to distribute AstDB shared families between Asterisk
+ instances. This includes inbound/outbound PUBLISH support for a new event
+ type, 'asterisk-db'.
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 13.2.0 to Asterisk 13.3.0 ------------
Modified: team/mjordan/trunk-astdb-cluster/configs/samples/pjsip.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk-astdb-cluster/configs/samples/pjsip.conf.sample?view=diff&rev=433003&r1=433002&r2=433003
==============================================================================
--- team/mjordan/trunk-astdb-cluster/configs/samples/pjsip.conf.sample (original)
+++ team/mjordan/trunk-astdb-cluster/configs/samples/pjsip.conf.sample Mon Mar 16 21:18:35 2015
@@ -73,6 +73,10 @@
; * Contains information about an outbound SIP registration
; * Phone Provisioning "phoneprov"
; * Contains information needed by res_phoneprov for autoprovisioning
+; * Inbound publication handler "inbound-publication"
+; * Defines a handler for received PUBLISH requests
+; * Outbound publisher "outbound-publish"
+; * Defines an entity to send PUBLISH requests to
; The following sections show example configurations for various scenarios.
; Most require a couple or more configuration types configured in concert.
@@ -586,6 +590,54 @@
;AUTH_ID=1000-auth ;automatically added by this module
;TRANSPORT_ID=transport-udp-nat ;automatically added by this module
;LABEL=1000 ;added by user
+
+;==============EXAMPLE PUBLISH CONFIGURATION================================
+; The production and handling of PUBLISH requests is broken into three different
+; sections: "inbound-publication", "asterisk-publication", and "outbound-publish".
+; An "inbound-publication" section defines how Asterisk will handle received
+; PUBLISH requests from a particular endpoint; an "asterisk-publication" section
+; specifically handles intra-Asterisk event types; and an "outbound-publish"
+; section defines how Asterisk will transmit PUBLISH requests to a particular
+; endpoint.
+
+; The following example demonstrates distributing device state to another
+; Asterisk instance. In this case, this example assumes that there is an
+; "endpoint" definition for the other Asterisk instance named "ast2". We'll
+; provide a small stub for this endpoint, but otherwise leave it undefined.
+
+; [ast2]
+; type=endpoint ; An endpoint instance for the "other" Asterisk instance
+;
+
+; To handle inbound device state updates, we define both an "inbound-publication"
+; section as well as an "asterisk-publication" section. The "inbound-publication"
+; defines a handler for an event type of "asterisk-devicestate" that maps to
+; the "asterisk-publication" section. Note that all event types for
+; inbound PUBLISH handlers prefix the event type(s) that they handle with
+; "event_". The value of the event type specifies the "asterisk-publication"
+; section that will define how we handle these events.
+
+; [ast2]
+; type=inbound-publication
+; event_asterisk-devicestate=ast2 ; Handle "asterisk-devicestate" events
+; ; using the "asterisk-publication" section
+; ; "ast2"
+
+; [ast2]
+; type=asterisk-publication
+; device_state=yes ; Specify that we will handle intra-Asterisk
+; ; device state updates
+
+; To PUBLISH our device state to endpoint "ast2", we define an "outbound-publish"
+; section. This section specifies that we will PUBLISH events of type
+; "asterisk-devicestate" to the SIP URI "sip:ast2 at my-awesome-service.com:5060".
+
+; [ast2]
+; type=outbound-publish
+; server_uri=sip:ast2 at my-awesome-service.com:5060 ; PUBLISH device states to this URI
+; event=asterisk-devicestate ; The event type to publish
+
+
; MODULE PROVIDING BELOW SECTION(S): res_pjsip
;==========================ENDPOINT SECTION OPTIONS=========================
@@ -930,3 +982,55 @@
; Common variables include LINE, LINEKEYS, etc.
; See phoneprov.conf.sample for others.
;type= ; Must be of type phoneprov (default: "")
+
+
+
+; MODULE(S) PROVIDING BELOW SECTION(S): res_pjsip_pubsub, res_pjsip_outbound_publish,
+; res_pjsip_publish_asterisk
+;=============================PUBLISH OPTIONS=================================
+; [inbound-publication]
+; type= ; Must be of type inbound-publication (default: "")
+; event_asterisk-devicestate= ; The asterisk-publication section that defines how
+ ; asterisk-devicestate PUBLISH requests are handled
+; event_asterisk-mwi= ; The asterisk-publication section that defines how
+ ; asterisk-mwi PUBLISH requests are handled
+; event_asterisk-db= ; The asterisk-publication section that defines how
+ ; asterisk-db PUBLISH requests are handled
+; endpoint= ; Endpoints that we should accept PUBLISH requests
+ ; from (default: "")
+
+; [outbound-publish]
+; type= ; Must be of type outbound-publish (default: "")
+; expiration= ; Expiration time for PUBLISH requests in seconds
+ ; (default: 3600)
+; outbound_auth= ; Authentication object to be used for outbound
+ ; publishes (default: "")
+; outbound_proxy= ; SIP URI of the outbound proxy used to send publishes
+ ; (default: "")
+; server_uri= ; SIP URI of the server and entity to publish to
+; from_uri= ; SIP URI to use in the From header
+; to_uri= ; SIP URI to use in the To header
+; max_auth_attempts= ; Maximum number of authentication attempts before
+ ; stopping the publication (default: 5)
+; event= ; Event type to publish (default: "")
+
+; [asterisk-publication]
+; type= ; Must be of type asterisk-publication (default: "")
+; devicestate_publish= ; Optional name of an outbound publish item that can be
+ ; used to publish a request for full device state information
+; mailboxstate_publish= ; Optional name of an outbound publish item that can be used
+ ; to publish a request for full mailbox state information
+; db_publish= ; Optional name of an outbound publish item that can be used
+ ; to publish a request for full AstDB shared family information
+; device_state= ; Permit incoming "asterisk-devicestate" events.
+ ; (default: No)
+; device_state_filter= ; Optional regular expression used to filter what devices
+ ; we accept events for.
+; mailbox_state= ; Permit incoming "asterisk-mailboxstate" events.
+ ; (default: No)
+; mailbox_state_filter= ; Optional regular expression used to filter what mailboxes
+ ; we accept events for.
+; db_state= ; Permit incoming "asterisk-db" events. (default: No)
+; db_state_filter= ; Optional regular expression used to filter what AstDB
+ ; shared families we accept events for.
+
Modified: team/mjordan/trunk-astdb-cluster/funcs/func_db.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk-astdb-cluster/funcs/func_db.c?view=diff&rev=433003&r1=433002&r2=433003
==============================================================================
--- team/mjordan/trunk-astdb-cluster/funcs/func_db.c (original)
+++ team/mjordan/trunk-astdb-cluster/funcs/func_db.c Mon Mar 16 21:18:35 2015
@@ -1,9 +1,9 @@
/*
* Asterisk -- An open source telephony toolkit.
*
- * Copyright (C) 2005-2015, Russell Bryant <russelb at clemson.edu>
- *
- * func_db.c adapted from the old app_db.c, copyright by the following people
+ * Copyright (C) 2005-2015, Russell Bryant <russelb at clemson.edu>
+ *
+ * func_db.c adapted from the old app_db.c, copyright by the following people
* Copyright (C) 2005, Mark Spencer <markster at digium.com>
* Copyright (C) 2003, Jefferson Noxon <jeff at debian.org>
*
@@ -23,7 +23,6 @@
* \brief Functions for interaction with the Asterisk database
*
* \author Russell Bryant <russelb at clemson.edu>
- * \author Matt Jordan <mjordan at digium.com>
*
* \ingroup functions
*/
@@ -53,30 +52,6 @@
<syntax argsep="/">
<parameter name="family" required="true" />
<parameter name="key" required="true" />
- </syntax>
- <description>
- <para>This function will read from or write a value to the Asterisk database. On a
- read, this function returns the corresponding value from the database, or blank
- if it does not exist. Reading a database value will also set the variable
- DB_RESULT. If you wish to find out if an entry exists, use the DB_EXISTS
- function.</para>
- </description>
- <see-also>
- <ref type="application">DBdel</ref>
- <ref type="function">DB_DELETE</ref>
- <ref type="application">DBdeltree</ref>
- <ref type="function">DB_EXISTS</ref>
- </see-also>
- </function>
- <function name="DB_SHARED" language="en_US">
- <synopsis>
- Create or delete a shared family in the Asterisk database.
- </synopsis>
- <syntax argsep="/">
- <parameter name="action" required="true">
- </parameter>
- <parameter name="type">
- </parameter>
</syntax>
<description>
<para>This function will read from or write a value to the Asterisk database. On a
@@ -148,6 +123,120 @@
<ref type="application">DBdeltree</ref>
</see-also>
</function>
+ <function name="DB_SHARED" language="en_US">
+ <synopsis>
+ W/O. Create or delete a shared family in the Asterisk database.
+ </synopsis>
+ <syntax>
+ <parameter name="action" required="true">
+ <enumlist>
+ <enum name="put">
+ <para>Create a shared family.</para>
+ </enum>
+ <enum name="delete">
+ <para>Delete a shared family.</para>
+ </enum>
+ </enumlist>
+ </parameter>
+ <parameter name="type">
+ <enumlist>
+ <enum name="global">
+ <para>
+ Create a global shared family.
+ </para>
+ </enum>
+ <enum name="unique">
+ <para>
+ Create a unique shared family.
+ </para>
+ </enum>
+ </enumlist>
+ </parameter>
+ </syntax>
+ <description>
+ <para>
+ This function will mark a family in the AstDB as shared
+ across a cluster of Asterisk servers. Updates to keys in
+ the shared family are distributed to the other Asterisk
+ servers in the cluster.
+ </para>
+ <para>
+ Families may be shared in one of two ways: 'global' or 'unique'.
+ </para>
+ <para>
+ A global shared family shares its keys/values across
+ Asterisk servers as a shared namespace. Any server that
+ changes a value in a global shared family will have that
+ same key be updated in the shared families of other servers.
+ </para>
+ <para>
+ A unique shared family shares its keys/values across
+ Asterisk servers, but the keys/values are stored in a
+ family matching the originating Asterisk server's
+ <replaceable>EID</replaceable>. Other Asterisk servers must
+ also have a shared family matching the originating Asterisk
+ server's shared family.
+ </para>
+ <note>
+ <para>The mechanism of sharing the information to other
+ Asterisk servers is independent of this function.</para>
+ </note>
+ <example title="Create global shared family">
+ ; Share AstDB family 'global_shared' globally across servers
+ same => n,Set(DB_SHARED(put,global)=global_shared)
+
+ ; Update to key/value 'foo/bar' will be distributed to
+ ; other Asterisk servers that have also shared the
+ ; 'global_shared' family
+ same => n,Set(DB(global_shared/foo)=bar)
+ </example>
+ <example title="Create unique shared family">
+ ; Share AstDB family 'unique_shared' uniquely across servers
+ same => n,Set(DB_SHARED(put,unique)=unique_shared)
+
+ ; Update to key/value 'foo/bar' will be distributed to
+ ; other Asterisk servers that have also shared the
+ ; 'unique_shared' family. Assuming this server's EID is
+ ; 11:11:11:11:11:11, the key will be stored in
+ ; '11:11:11:11:11:11/unique_shared/foo' with value 'bar'
+ ; on those servers.
+ same => n,Set(DB(unique_shared/foo)=bar)
+ </example>
+ <example title="Delete global shared family">
+ ; Share AstDB family 'global_shared' globally across servers
+ same => n,Set(DB_SHARED(put,global)=global_shared)
+
+ ; This update will be shared
+ same => n,Set(DB(global_shared/foo)=bar)
+
+ ; Remove the shared status of 'global_shared'
+ same => n,Set(DB_SHARED(delete)=global_shared)
+
+ ; This update will not be shared
+ same => n,Set(DB(global_shared/foo)=unbar)
+ </example>
+ </description>
+ <see-also>
+ <ref type="function">DB</ref>
+ <ref type="function">DB_SHARED_EXISTS</ref>
+ </see-also>
+ </function>
+ <function name="DB_SHARED_EXISTS" language="en_US">
+ <synopsis>
+ Check to see if a family is shared.
+ </synopsis>
+ <syntax>
+ <parameter name="family" required="true" />
+ </syntax>
+ <description>
+ <para>This function will check to see if a family is shared between
+ Asteris instances. If so, the function will return <literal>1</literal>.
+ If not, it will return <literal>0</literal>.</para>
+ </description>
+ <see-also>
+ <ref type="function">DB_SHARED</ref>
+ </see-also>
+ </function>
***/
static int function_db_read(struct ast_channel *chan, const char *cmd,
@@ -386,7 +475,6 @@
} else {
ast_copy_string(buf, "0", len);
}
- pbx_builtin_setvar_helper(chan, "DB_RESULT", buf);
return 0;
}
@@ -425,9 +513,9 @@
if (!strcasecmp(args.action, "put")) {
if (ast_strlen_zero(args.type) || !strcasecmp(args.type, "global")) {
- share_type = SHARED_DB_TYPE_GLOBAL;
+ share_type = DB_SHARE_TYPE_GLOBAL;
} else if (!strcasecmp(args.type, "unique")) {
- share_type = SHARED_DB_TYPE_UNIQUE;
+ share_type = DB_SHARE_TYPE_UNIQUE;
} else {
ast_log(LOG_WARNING, "DB_SHARED: Unknown 'type' %s\n", args.type);
return -1;
@@ -438,7 +526,7 @@
ast_debug(2, "Failed to create shared family '%s'\n", value);
} else {
ast_verb(4, "Created %s shared family '%s'\n",
- share_type == SHARED_DB_TYPE_GLOBAL ? "GLOBAL" : "UNIQUE",
+ share_type == DB_SHARE_TYPE_GLOBAL ? "GLOBAL" : "UNIQUE",
value);
}
} else if (!strcasecmp(args.action, "delete")) {
Modified: team/mjordan/trunk-astdb-cluster/include/asterisk/astdb.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk-astdb-cluster/include/asterisk/astdb.h?view=diff&rev=433003&r1=433002&r2=433003
==============================================================================
--- team/mjordan/trunk-astdb-cluster/include/asterisk/astdb.h (original)
+++ team/mjordan/trunk-astdb-cluster/include/asterisk/astdb.h Mon Mar 16 21:18:35 2015
@@ -35,9 +35,9 @@
enum ast_db_shared_type {
/* Items in the shared family are common across all Asterisk instances */
- SHARED_DB_TYPE_GLOBAL = 0,
+ DB_SHARE_TYPE_GLOBAL = 0,
/*! Items in the shared family are made unique across all Asterisk instances */
- SHARED_DB_TYPE_UNIQUE,
+ DB_SHARE_TYPE_UNIQUE,
};
/*! \brief An actual entry in the AstDB */
@@ -148,7 +148,6 @@
*/
void ast_db_refresh_shared(void);
-
/*!
* \since 14.0.0
* \brief Add a new shared family
Modified: team/mjordan/trunk-astdb-cluster/include/asterisk/event_defs.h
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk-astdb-cluster/include/asterisk/event_defs.h?view=diff&rev=433003&r1=433002&r2=433003
==============================================================================
--- team/mjordan/trunk-astdb-cluster/include/asterisk/event_defs.h (original)
+++ team/mjordan/trunk-astdb-cluster/include/asterisk/event_defs.h Mon Mar 16 21:18:35 2015
@@ -58,10 +58,8 @@
AST_EVENT_ACL_CHANGE = 0x0b,
/*! Send out a ping for debugging distributed events */
AST_EVENT_PING = 0x0c,
- /*! Send out a shared database event */
- AST_EVENT_DB_SHARED = 0x0d,
/*! Number of event types. This should be the last event type + 1 */
- AST_EVENT_TOTAL = 0x0e,
+ AST_EVENT_TOTAL = 0x0d,
};
/*! \brief Event Information Element types */
@@ -304,38 +302,8 @@
* Payload type: UINT
*/
AST_EVENT_IE_CACHABLE = 0x003d,
- /*!
- * \brief AstDB Family
- * Used by: AST_EVENT_DB_SHARED
- * Payload type: STR
- */
- AST_EVENT_IE_DB_FAMILY = 0x003e,
- /*!
- * \brief AstDB action to take
- * Used by: AST_EVENT_DB_SHARED
- * Payload type: STR
- */
- AST_EVENT_ID_DB_ACTION_TYPE = 0x003f,
- /*!
- * \brief AstDB share type
- * Used by: AST_EVENT_DB_SHARED
- * Payload type: UINT
- */
- AST_EVENT_IE_DB_SHARE_TYPE = 0x0040,
- /*!
- * \brief AstDB key
- * Used by: AST_EVENT_DB_SHARED
- * Payload type: STR
- */
- AST_EVENT_IE_DB_KEY = 0x0041,
- /*!
- * \brief AstDB value
- * Used by: AST_EVENT_DB_SHARED
- * Payload type: STR
- */
- AST_EVENT_IE_DB_VALUE = 0x0042,
/*! \brief Must be the last IE value +1 */
- AST_EVENT_IE_TOTAL = 0x0043,
+ AST_EVENT_IE_TOTAL = 0x003e,
};
/*!
Modified: team/mjordan/trunk-astdb-cluster/main/db.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk-astdb-cluster/main/db.c?view=diff&rev=433003&r1=433002&r2=433003
==============================================================================
--- team/mjordan/trunk-astdb-cluster/main/db.c (original)
+++ team/mjordan/trunk-astdb-cluster/main/db.c Mon Mar 16 21:18:35 2015
@@ -51,7 +51,6 @@
#include "asterisk/cli.h"
#include "asterisk/utils.h"
#include "asterisk/manager.h"
-#include "asterisk/event.h"
/*** DOCUMENTATION
<manager name="DBGet" language="en_US">
@@ -113,7 +112,11 @@
static int doexit;
static int dosync;
-/*! \brief A container of families to share across Asterisk instances */
+/*!
+ * \brief A container of families to share across Asterisk instances.
+ * \note Entries in this container should be treated as immutable. The container
+ * needs locking; the entries do not.
+ */
static struct ao2_container *shared_families;
/*! \brief The Stasis topic for shared families */
@@ -227,9 +230,7 @@
return entry;
}
-/*! \internal
- * \brief AO2 destructor for \c ast_db_shared_family
- */
+/*! \internal \brief AO2 destructor for \c ast_db_shared_family */
static void shared_db_family_dtor(void *obj)
{
struct ast_db_shared_family *family = obj;
@@ -425,7 +426,7 @@
ao2_link_flags(shared_families, shared_family, OBJ_NOLOCK);
db_put_common(SHARED_FAMILY, shared_family->name,
- share_type == SHARED_DB_TYPE_UNIQUE ? "UNIQUE" : "GLOBAL", 0);
+ share_type == DB_SHARE_TYPE_UNIQUE ? "UNIQUE" : "GLOBAL", 0);
ao2_ref(shared_family, -1);
@@ -448,13 +449,24 @@
return res;
}
+/*!
+ * \internal
+ * \brief Update remote instances that a shared family key/value was updated
+ *
+ * \param family The AstDB family
+ * \param key The AstDB key
+ * \param value The AstDB value
+ *
+ * \retval 0 entry was processed successfully
+ * \retval -1 error
+ */
static int db_entry_put_shared(const char *family, const char *key, const char *value)
{
struct ast_db_shared_family *shared_family;
struct ast_db_shared_family *clone;
/* See if we are shared */
- shared_family = ao2_find(shared_families, family, OBJ_SEARCH_PARTIAL_KEY);
+ shared_family = ao2_find(shared_families, family, OBJ_SEARCH_KEY);
if (!shared_family) {
return 0;
}
@@ -480,13 +492,24 @@
return 0;
}
+/*!
+ * \internal
+ * \brief Update remote instances that a shared family key/value was deleted
+ *
+ * \param family The AstDB family
+ * \param key The AstDB key
+ * \param value The AstDB value
+ *
+ * \retval 0 entry was processed successfully
+ * \retval -1 error
+ */
static int db_entry_del_shared(const char *family, const char *key)
{
struct ast_db_shared_family *shared_family;
struct ast_db_shared_family *clone;
/* See if we are shared */
- shared_family = ao2_find(shared_families, family, OBJ_SEARCH_PARTIAL_KEY);
+ shared_family = ao2_find(shared_families, family, OBJ_SEARCH_KEY);
if (!shared_family) {
return 0;
}
@@ -542,6 +565,18 @@
return res;
}
+/*!
+ * \internal
+ * \brief Common routine to update an entry in the AstDB
+ *
+ * \param family The AstDB family
+ * \param key The AstDB key
+ * \param value The AstDB value
+ * \param share If non-zero, try to inform other instances that the key was updated
+ *
+ * \retval 0 success
+ * \retval -1 error
+ */
static int db_put_common(const char *family, const char *key, const char *value, int share)
{
char fullkey[MAX_DB_FIELD];
@@ -652,6 +687,17 @@
return db_get_common(family, key, out, -1);
}
+/*!
+ * \internal
+ * \brief Common routine to delete an entry in the AstDB
+ *
+ * \param family The AstDB family
+ * \param key The AstDB key
+ * \param share If non-zero, try to inform other instances that the key was deleted
+ *
+ * \retval 0 success
+ * \retval -1 error
+ */
static int db_del_common(const char *family, const char *key, int share)
{
char fullkey[MAX_DB_FIELD];
@@ -680,7 +726,7 @@
}
ast_mutex_unlock(&dblock);
- return res;
+ return res;
}
int ast_db_del(const char *family, const char *key)
@@ -688,6 +734,17 @@
return db_del_common(family, key, 1);
}
+/*!
+ * \internal
+ * \brief Common routine to delete an entire tree in the AstDB
+ *
+ * \param family The AstDB family
+ * \param key The AstDB key. May be NULL.
+ * \param share If non-zero, try to inform other instances that the key was deleted
+ *
+ * \retval 0 success
+ * \retval -1 error
+ */
static int db_deltree_common(const char *family, const char *keytree, int share)
{
sqlite3_stmt *stmt = deltree_stmt;
@@ -723,7 +780,7 @@
}
ast_mutex_unlock(&dblock);
- return res;
+ return res;
}
int ast_db_deltree(const char *family, const char *keytree)
@@ -897,9 +954,9 @@
}
if (!strcasecmp(a->argv[4], "unique")) {
- share_type = SHARED_DB_TYPE_UNIQUE;
+ share_type = DB_SHARE_TYPE_UNIQUE;
} else if (!strcasecmp(a->argv[4], "global")) {
- share_type = SHARED_DB_TYPE_GLOBAL;
+ share_type = DB_SHARE_TYPE_GLOBAL;
} else {
ast_cli(a->fd, "Unknown share type: '%s'\n", a->argv[4]);
return CLI_SUCCESS;
@@ -975,6 +1032,7 @@
return CLI_SUCCESS;
}
+/*! \internal \brief Helper for CLI commands that print the AstDB */
static int print_database_show(struct ast_cli_args *a, sqlite3_stmt *stmt)
{
int counter = 0;
@@ -1005,7 +1063,7 @@
++counter;
ast_cli(a->fd, "%-50s: %-25s %s\n", key_s, value_s,
- shared_family ? (shared_family->share_type == SHARED_DB_TYPE_UNIQUE ? "(U)" : "(G)") : "");
+ shared_family ? (shared_family->share_type == DB_SHARE_TYPE_UNIQUE ? "(U)" : "(G)") : "");
ao2_cleanup(shared_family);
ast_free(family_s);
@@ -1324,7 +1382,8 @@
return NULL;
}
-int ast_db_publish_shared_message(struct stasis_message_type *type, struct ast_db_shared_family *shared_family, struct ast_eid *eid)
+int ast_db_publish_shared_message(struct stasis_message_type *type,
+ struct ast_db_shared_family *shared_family, struct ast_eid *eid)
{
struct stasis_message *message;
@@ -1371,18 +1430,17 @@
ao2_ref(clone, -1);
ao2_ref(shared_family, -1);
}
- ao2_iterator_destroy(&it_shared_families);
-}
-
-static struct ast_event *db_del_shared_type_to_event(struct stasis_message *message)
-{
- return NULL;
+ ao2_iterator_destroy(&it_shared_families);
}
static struct ast_json *db_entries_to_json(struct ast_db_entry *entry)
{
struct ast_json *json;
struct ast_db_entry *cur;
+
+ if (!entry) {
+ return ast_json_null();
+ }
json = ast_json_array_create();
if (!json) {
@@ -1414,17 +1472,27 @@
{
struct stasis_message_type *type = stasis_message_type(message);
struct ast_db_shared_family *shared_family;
+ struct ast_json *entries;
+
+ if (type != ast_db_put_shared_type() && type != ast_db_del_shared_type()) {
+ return NULL;
+ }
shared_family = stasis_message_data(message);
if (!shared_family) {
+ return NULL;
+ }
+
+ entries = db_entries_to_json(shared_family->entries);
+ if (!entries) {
return NULL;
}
return ast_json_pack("{s: s, s: s, s: s, s: o}",
"verb", type == ast_db_put_shared_type() ? "put" : "delete",
"family", shared_family->name,
- "share_type", shared_family->share_type == SHARED_DB_TYPE_UNIQUE ? "unique" : "global",
- "entries", shared_family->entries ? db_entries_to_json(shared_family->entries) : ast_json_null());
+ "share_type", shared_family->share_type == DB_SHARE_TYPE_UNIQUE ? "unique" : "global",
+ "entries", entries);
}
struct stasis_topic *ast_db_cluster_topic(void)
@@ -1468,7 +1536,7 @@
}
ao2_ref(shared_check, -1);
- if (shared_family->share_type == SHARED_DB_TYPE_UNIQUE) {
+ if (shared_family->share_type == DB_SHARE_TYPE_UNIQUE) {
char eid_workspace[20];
/* Length is family + '/' + EID length (20) + 1 */
@@ -1527,7 +1595,9 @@
ast_manager_unregister("DBDel");
ast_manager_unregister("DBDelTree");
- ao2_cleanup(db_cluster_topic);
+ ao2_ref(message_router, -1);
+ message_router = NULL;
+ ao2_ref(db_cluster_topic, -1);
db_cluster_topic = NULL;
STASIS_MESSAGE_TYPE_CLEANUP(ast_db_put_shared_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_db_del_shared_type);
@@ -1572,9 +1642,9 @@
}
if (!strcasecmp(cur->data, "unique")) {
- share_type = SHARED_DB_TYPE_UNIQUE;
+ share_type = DB_SHARE_TYPE_UNIQUE;
} else if (!strcasecmp(cur->data, "global")) {
- share_type = SHARED_DB_TYPE_GLOBAL;
+ share_type = DB_SHARE_TYPE_GLOBAL;
} else {
continue;
}
@@ -1596,8 +1666,7 @@
db_cluster_topic = stasis_topic_create("ast_db_cluster_topic");
if (!db_cluster_topic) {
- ao2_ref(shared_families, -1);
- return -1;
+ goto error_cleanup;
}
STASIS_MESSAGE_TYPE_INIT(ast_db_put_shared_type);
@@ -1605,9 +1674,7 @@
message_router = stasis_message_router_create_pool(ast_db_cluster_topic());
if (!message_router) {
- ao2_ref(db_cluster_topic, -1);
- ao2_ref(shared_families, -1);
- return -1;
+ goto error_cleanup;
}
stasis_message_router_add(message_router, ast_db_put_shared_type(),
db_put_shared_msg_cb, NULL);
@@ -1615,18 +1682,14 @@
db_del_shared_msg_cb, NULL);
if (db_init()) {
- ao2_ref(db_cluster_topic, -1);
- ao2_ref(shared_families, -1);
- return -1;
+ goto error_cleanup;
}
restore_shared_families();
ast_cond_init(&dbcond, NULL);
if (ast_pthread_create_background(&syncthread, NULL, db_sync_thread, NULL)) {
- ao2_ref(db_cluster_topic, -1);
- ao2_ref(shared_families, -1);
- return -1;
+ goto error_cleanup;
}
ast_register_atexit(astdb_atexit);
@@ -1636,4 +1699,12 @@
ast_manager_register_xml_core("DBDel", EVENT_FLAG_SYSTEM, manager_dbdel);
ast_manager_register_xml_core("DBDelTree", EVENT_FLAG_SYSTEM, manager_dbdeltree);
return 0;
-}
+
+error_cleanup:
+ ao2_cleanup(message_router);
+ ao2_cleanup(db_cluster_topic);
+ STASIS_MESSAGE_TYPE_CLEANUP(ast_db_put_shared_type);
+ STASIS_MESSAGE_TYPE_CLEANUP(ast_db_del_shared_type);
+ ao2_cleanup(shared_families);
+ return -1;
+}
Modified: team/mjordan/trunk-astdb-cluster/res/res_pjsip_publish_asterisk.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk-astdb-cluster/res/res_pjsip_publish_asterisk.c?view=diff&rev=433003&r1=433002&r2=433003
==============================================================================
--- team/mjordan/trunk-astdb-cluster/res/res_pjsip_publish_asterisk.c (original)
+++ team/mjordan/trunk-astdb-cluster/res/res_pjsip_publish_asterisk.c Mon Mar 16 21:18:35 2015
@@ -363,7 +363,7 @@
if (!eid || ast_eid_cmp(&ast_eid_default, eid)) {
/* If the event is aggregate, unknown, or didn't originate from this
* server, don't send it out. */
- return;
+ return;
}
shared_family = stasis_message_data(msg);
@@ -798,9 +798,9 @@
ast_sorcery_object_get_id(config));
return -1;
} else if (!strcasecmp(str_share_type, "global")) {
- share_type = SHARED_DB_TYPE_GLOBAL;
+ share_type = DB_SHARE_TYPE_GLOBAL;
} else if (!strcasecmp(str_share_type, "unique")) {
- share_type = SHARED_DB_TYPE_UNIQUE;
+ share_type = DB_SHARE_TYPE_UNIQUE;
} else {
ast_debug(1, "Received bad AstDB state event for resource '%s': unknown verb '%s'\n",
ast_sorcery_object_get_id(config), str_share_type);
@@ -1298,7 +1298,7 @@
for (i = 0; i < ARRAY_LEN(event_publisher_handlers); i++) {
if (ast_sip_register_event_publisher_handler(event_publisher_handlers[i])) {
ast_log(LOG_WARNING, "Unable to register event publisher handler %s\n",
- event_publisher_handlers[i]->event_name);
+ event_publisher_handlers[i]->event_name);
for (j = 0; j < ARRAY_LEN(&publish_handlers); j++) {
ast_sip_unregister_publish_handler(publish_handlers[j]);
}
Modified: team/mjordan/trunk-astdb-cluster/tests/test_db.c
URL: http://svnview.digium.com/svn/asterisk/team/mjordan/trunk-astdb-cluster/tests/test_db.c?view=diff&rev=433003&r1=433002&r2=433003
==============================================================================
--- team/mjordan/trunk-astdb-cluster/tests/test_db.c (original)
+++ team/mjordan/trunk-astdb-cluster/tests/test_db.c Mon Mar 16 21:18:35 2015
@@ -4,7 +4,6 @@
* Copyright (C) 2011-2015, Digium, Inc.
*
* Terry Wilson <twilson at digium.com>
- * Matt Jordan <mjordan at digium.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
@@ -22,7 +21,6 @@
* \brief AstDB Unit Tests
*
* \author Terry Wilson <twilson at digium.com>
- * \author Matt Jordan <mjordan at digium.com>
*
*/
@@ -386,6 +384,16 @@
return res;
}
+/*!
+ * \brief Test the AstDB for the given family, key, value tuple
+ *
+ * As annoying as it is, it's actually really hard to synchronize on when the
+ * AstDB updates itself from the received publication of a shared family value.
+ * This is because while we can synchronize on the delivery to a topic, we can't
+ * synchronize that the AstDB handler's for that topic has written the value out.
+ * Hence, we use this loop - if we don't get a value written within 1000 usec,
+ * something is definitely wrong and we should just fail the unit test.
+ */
#define TEST_FOR_VALUE(family, key, value) do { \
int i; \
for (i = 0; i < 10; i++) { \
@@ -416,22 +424,22 @@
break;
}
- res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, SHARED_DB_TYPE_GLOBAL);
+ res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, DB_SHARE_TYPE_GLOBAL);
ast_test_validate(test, res == 0, "Creating global shared area");
res = ast_db_is_shared(GLOBAL_SHARED_FAMILY);
ast_test_validate(test, res == 1, "Test existance of global shared area");
- res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, SHARED_DB_TYPE_GLOBAL);
+ res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, DB_SHARE_TYPE_GLOBAL);
ast_test_validate(test, res != 0, "Creating duplicate global shared area");
- res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, SHARED_DB_TYPE_UNIQUE);
+ res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, DB_SHARE_TYPE_UNIQUE);
ast_test_validate(test, res != 0, "Creating duplicate unique of global shared area");
- res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, SHARED_DB_TYPE_UNIQUE);
+ res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, DB_SHARE_TYPE_UNIQUE);
ast_test_validate(test, res == 0, "Creating unique shared area");
res = ast_db_is_shared(UNIQUE_SHARED_FAMILY);
ast_test_validate(test, res == 1, "Test existance of unique shared area");
- res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, SHARED_DB_TYPE_UNIQUE);
+ res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, DB_SHARE_TYPE_UNIQUE);
ast_test_validate(test, res != 0, "Creating duplicate unique shared area");
- res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, SHARED_DB_TYPE_GLOBAL);
+ res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, DB_SHARE_TYPE_GLOBAL);
ast_test_validate(test, res != 0, "Creating duplicate global of unique shared area");
ast_db_del_shared(GLOBAL_SHARED_FAMILY);
@@ -456,7 +464,7 @@
break;
}
- res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, SHARED_DB_TYPE_GLOBAL);
+ res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, DB_SHARE_TYPE_GLOBAL);
ast_test_validate(test, res == 0, "Creating global shared area");
res = ast_db_del_shared(GLOBAL_SHARED_FAMILY);
ast_test_validate(test, res == 0, "Deletion of global shared area");
@@ -465,7 +473,7 @@
res = ast_db_del_shared(GLOBAL_SHARED_FAMILY);
ast_test_validate(test, res != 0, "Allowed duplicate deletion of global shared area");
- res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, SHARED_DB_TYPE_UNIQUE);
+ res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, DB_SHARE_TYPE_UNIQUE);
ast_test_validate(test, res == 0, "Creating unique shared area");
res = ast_db_del_shared(UNIQUE_SHARED_FAMILY);
ast_test_validate(test, res == 0, "Deletion of unique shared area");
@@ -507,7 +515,7 @@
/* Create a key that is not published due to not being shared yet */
res = ast_db_put(UNIQUE_SHARED_FAMILY, "foo", "bar");
ast_test_validate(test, res == 0, "Creation of non-published test key");
- res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, SHARED_DB_TYPE_UNIQUE);
+ res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, DB_SHARE_TYPE_UNIQUE);
ast_test_validate(test, res == 0, "Creation of unique shared area");
/* Publish a new key */
@@ -562,7 +570,7 @@
/* Create a key that is not published due to not being shared yet */
res = ast_db_put(GLOBAL_SHARED_FAMILY, "foo", "bar");
ast_test_validate(test, res == 0, "Creation of non-published test key");
- res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, SHARED_DB_TYPE_GLOBAL);
+ res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, DB_SHARE_TYPE_GLOBAL);
ast_test_validate(test, res == 0, "Creation of global shared area");
/* Publish a new key */
@@ -584,7 +592,7 @@
ast_db_deltree(GLOBAL_SHARED_FAMILY, "");
ast_db_del_shared(GLOBAL_SHARED_FAMILY);
- return AST_TEST_PASS;
+ return AST_TEST_PASS;
}
AST_TEST_DEFINE(test_ast_db_put_shared_unique_update)
@@ -613,12 +621,12 @@
ast_test_status_update(test, "Verifying unique shared area can be updated\n");
- shared_family = ast_db_shared_family_alloc(UNIQUE_SHARED_FAMILY, SHARED_DB_TYPE_UNIQUE);
+ shared_family = ast_db_shared_family_alloc(UNIQUE_SHARED_FAMILY, DB_SHARE_TYPE_UNIQUE);
ast_test_validate(test, shared_family != NULL);
shared_family->entries = ast_db_entry_create("foo", "bar");
ast_test_validate(test, shared_family->entries != NULL);
- res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, SHARED_DB_TYPE_UNIQUE);
+ res = ast_db_put_shared(UNIQUE_SHARED_FAMILY, DB_SHARE_TYPE_UNIQUE);
ast_test_validate(test, res == 0, "Creation of unique shared area");
ast_db_publish_shared_message(ast_db_put_shared_type(), shared_family, &eid);
@@ -634,7 +642,7 @@
ao2_ref(shared_family, -1);
ast_test_status_update(test, "Verifying unique non-shared area is not updated\n");
- shared_family = ast_db_shared_family_alloc(UNIQUE_SHARED_FAMILY, SHARED_DB_TYPE_UNIQUE);
+ shared_family = ast_db_shared_family_alloc(UNIQUE_SHARED_FAMILY, DB_SHARE_TYPE_UNIQUE);
ast_test_validate(test, shared_family != NULL);
shared_family->entries = ast_db_entry_create("foo", "yackity");
ast_test_validate(test, shared_family->entries != NULL);
@@ -675,12 +683,12 @@
ast_test_status_update(test, "Verifying global shared area can be updated\n");
- shared_family = ast_db_shared_family_alloc(GLOBAL_SHARED_FAMILY, SHARED_DB_TYPE_GLOBAL);
+ shared_family = ast_db_shared_family_alloc(GLOBAL_SHARED_FAMILY, DB_SHARE_TYPE_GLOBAL);
ast_test_validate(test, shared_family != NULL);
shared_family->entries = ast_db_entry_create("foo", "bar");
ast_test_validate(test, shared_family->entries != NULL);
- res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, SHARED_DB_TYPE_GLOBAL);
+ res = ast_db_put_shared(GLOBAL_SHARED_FAMILY, DB_SHARE_TYPE_GLOBAL);
ast_test_validate(test, res == 0, "Creation of global shared area");
ast_db_publish_shared_message(ast_db_put_shared_type(), shared_family, &eid);
@@ -696,7 +704,7 @@
ao2_ref(shared_family, -1);
ast_test_status_update(test, "Verifying global non-shared area is not updated\n");
[... 19 lines stripped ...]
More information about the asterisk-commits
mailing list