diff --git a/libs/libblade/libblade.vcxproj b/libs/libblade/libblade.vcxproj
index 8cb58199b1..33a9493001 100644
--- a/libs/libblade/libblade.vcxproj
+++ b/libs/libblade/libblade.vcxproj
@@ -193,7 +193,6 @@
-
@@ -207,7 +206,6 @@
-
@@ -217,7 +215,6 @@
-
@@ -232,7 +229,6 @@
-
diff --git a/libs/libblade/libblade.vcxproj.filters b/libs/libblade/libblade.vcxproj.filters
index f3392d90c6..c8d2468fe3 100644
--- a/libs/libblade/libblade.vcxproj.filters
+++ b/libs/libblade/libblade.vcxproj.filters
@@ -60,9 +60,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -75,9 +72,6 @@
Source Files
-
- Source Files
-
Source Files
@@ -131,9 +125,6 @@
Header Files
-
- Header Files
-
Header Files
@@ -146,9 +137,6 @@
Header Files
-
- Header Files
-
Header Files
diff --git a/libs/libblade/src/blade_channel.c b/libs/libblade/src/blade_channel.c
index 419d9e89ca..c976563803 100644
--- a/libs/libblade/src/blade_channel.c
+++ b/libs/libblade/src/blade_channel.c
@@ -35,6 +35,7 @@
struct blade_channel_s {
const char *name;
+ blade_channel_flags_t flags;
ks_rwl_t *lock;
ks_hash_t *authorizations;
};
@@ -59,7 +60,7 @@ static void blade_channel_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t
}
}
-KS_DECLARE(ks_status_t) blade_channel_create(blade_channel_t **bcP, ks_pool_t *pool, const char *name)
+KS_DECLARE(ks_status_t) blade_channel_create(blade_channel_t **bcP, ks_pool_t *pool, const char *name, blade_channel_flags_t flags)
{
blade_channel_t *bc = NULL;
@@ -69,6 +70,7 @@ KS_DECLARE(ks_status_t) blade_channel_create(blade_channel_t **bcP, ks_pool_t *p
bc = ks_pool_alloc(pool, sizeof(blade_channel_t));
bc->name = ks_pstrdup(pool, name);
+ bc->flags = flags;
ks_rwl_create(&bc->lock, pool);
ks_assert(bc->lock);
@@ -99,6 +101,12 @@ KS_DECLARE(const char *) blade_channel_name_get(blade_channel_t *bc)
return bc->name;
}
+KS_DECLARE(blade_channel_flags_t) blade_channel_flags_get(blade_channel_t *bc)
+{
+ ks_assert(bc);
+ return bc->flags;
+}
+
KS_DECLARE(ks_status_t) blade_channel_read_lock(blade_channel_t *bc)
{
ks_assert(bc);
diff --git a/libs/libblade/src/blade_identity.c b/libs/libblade/src/blade_identity.c
index 49254b9071..582f047a3b 100644
--- a/libs/libblade/src/blade_identity.c
+++ b/libs/libblade/src/blade_identity.c
@@ -37,9 +37,13 @@ struct blade_identity_s {
const char *uri;
const char *components;
- const char *name;
- const char *domain;
- const char *resource;
+
+ const char *scheme;
+ const char *user;
+ const char *host;
+ const char *port;
+ ks_port_t portnum;
+ const char *path;
ks_hash_t *parameters;
};
@@ -89,10 +93,30 @@ KS_DECLARE(ks_status_t) blade_identity_destroy(blade_identity_t **biP)
return KS_STATUS_SUCCESS;
}
+void blade_identity_reset(blade_identity_t *bi)
+{
+ ks_assert(bi);
+
+ bi->scheme = NULL;
+ bi->user = NULL;
+ bi->host = NULL;
+ bi->port = NULL;
+ bi->portnum = 0;
+ bi->path = NULL;
+
+ if (bi->uri) {
+ ks_pool_free(&bi->uri);
+ ks_pool_free(&bi->components);
+ }
+ if (bi->parameters) ks_hash_destroy(&bi->parameters);
+}
+
KS_DECLARE(ks_status_t) blade_identity_parse(blade_identity_t *bi, const char *uri)
{
+ ks_status_t ret = KS_STATUS_SUCCESS;
char *tmp = NULL;
char *tmp2 = NULL;
+ char terminator = '\0';
ks_pool_t *pool = NULL;
ks_assert(bi);
@@ -102,59 +126,221 @@ KS_DECLARE(ks_status_t) blade_identity_parse(blade_identity_t *bi, const char *u
pool = ks_pool_get(bi);
- if (bi->uri) {
- ks_pool_free(&bi->uri);
- ks_pool_free(&bi->components);
- }
+ blade_identity_reset(bi);
+
bi->uri = ks_pstrdup(pool, uri);
bi->components = tmp = ks_pstrdup(pool, uri);
- bi->name = tmp;
- if (!(tmp = strchr(tmp, '@'))) return KS_STATUS_FAIL;
+ // Supported components with pseudo regex
+ // [user@] [:port] [/path] [;param1=value1] [;param2=value2]
+
+ // scheme is mandatory to simplify the parser for now, it must start with mandatory: :
+ bi->scheme = tmp;
+ if (!(tmp = strchr(tmp, ':'))) {
+ ret = KS_STATUS_FAIL;
+ goto done;
+ }
+ // if found, null terminate scheme portion
*tmp++ = '\0';
+ // may have trailing '/' characters which are optional, this is not perfect it should probably only match a count of 0 or 2 explicitly
+ while (*tmp && *tmp == '/') ++tmp;
+ // must have more data to define at least a host
+ if (!*tmp) {
+ ret = KS_STATUS_FAIL;
+ goto done;
+ }
- bi->domain = tmp2 = tmp;
- if ((tmp = strchr(tmp, '/'))) {
- *tmp++ = '\0';
- bi->resource = tmp2 = tmp;
- } else tmp = tmp2;
+ if (!(*bi->scheme)) {
+ ret = KS_STATUS_FAIL;
+ goto done;
+ }
- if ((tmp = strchr(tmp, '?'))) {
- *tmp++ = '\0';
+ // next component may be the user or the host, so it may start with optional: @
+ // or it may skip to the host, which may be terminated by an optional port, optional path, optional parameters, or the end of the uri
+ // which means checking if an '@' appears before the next ':' for port, '/' for path, or ';' for parameters, if @ appears at all then it appears before end of the uri
+ // @todo need to account for host being encapsulated by '[' and ']' as in the case of an IPV6 host to distinguish from the port, but for simplicity allow any
+ // host to be encapsulated in which case if the string starts with a '[' here, then it MUST be the host and it MUST be terminated with the matching ']' rather than other
+ // optional component terminators
+ if (!(tmp2 = strpbrk(tmp, "@:/;"))) {
+ // none of the terminators are found, treat the remaining string as a host
+ bi->host = tmp;
+ goto done;
+ }
- while (tmp) {
- char *key = tmp;
- char *val = NULL;
- if (!(tmp = strchr(tmp, '='))) return KS_STATUS_FAIL;
- *tmp++ = '\0';
- val = tmp;
- if ((tmp = strchr(tmp, '&'))) {
- *tmp++ = '\0';
- }
+ // grab the terminator and null terminate for the next component
+ terminator = *tmp2;
+ *tmp2++ = '\0';
- if (!bi->parameters) {
- ks_hash_create(&bi->parameters, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
- ks_assert(bi->parameters);
- }
- ks_hash_insert(bi->parameters, key, val);
+ if (terminator == '@') {
+ // if the terminator was an '@', then we have a user component before the host
+ bi->user = tmp;
+
+ tmp = tmp2;
+
+ if (!(*bi->user)) {
+ ret = KS_STATUS_FAIL;
+ goto done;
+ }
+
+ // repeat the same as above, except without looking for '@', to find only the end of the host, parsing to the same point as above if user was not found
+ if (!(tmp2 = strpbrk(tmp, ":/;"))) {
+ // none of the terminators are found, treat the remaining string as a host
+ bi->host = tmp;
+ goto done;
+ }
+
+ // grab the terminator and null terminate for the next component
+ terminator = *tmp2;
+ *tmp2++ = '\0';
+ }
+
+ // at this point the user portion has been parsed if it exists, the host portion has been terminated, and there is still data remaining to parse
+ // @todo need to account for host being encapsulated by '[' and ']' as in the case of an IPV6 host to distinguish from the port, but for simplicity allow any
+ // host to be encapsulated in which case the terminator MUST be the closing ']'
+ bi->host = tmp;
+ tmp = tmp2;
+
+ if (!(*bi->host)) {
+ ret = KS_STATUS_FAIL;
+ goto done;
+ }
+
+ if (terminator == ':') {
+ // port terminator
+ bi->port = tmp;
+
+ // next component must be the port, which may be terminated by an optional path, optional parameters, or the end of the uri
+ // which means checking if a '/' for path, or ';' for parameters
+ if (!(tmp2 = strpbrk(tmp, "/;"))) {
+ // none of the terminators are found, treat the remaining string as a port
+ goto done;
+ }
+
+ terminator = *tmp2;
+ *tmp2++ = '\0';
+
+ tmp = tmp2;
+
+ if (!(*bi->port)) {
+ ret = KS_STATUS_FAIL;
+ goto done;
+ }
+
+ // @todo sscanf bi->port into bi->portnum and validate that it is a valid port number
+ }
+
+ if (terminator == '/') {
+ // path terminator
+ bi->path = tmp;
+
+ // next component must be the path, which may be terminated by optional parameters, or the end of the uri
+ // which means checking ';' for parameters
+ if (!(tmp2 = strpbrk(tmp, ";"))) {
+ // none of the terminators are found, treat the remaining string as a path
+ goto done;
+ }
+
+ terminator = *tmp2;
+ *tmp2++ = '\0';
+
+ tmp = tmp2;
+
+ if (!(*bi->path)) {
+ ret = KS_STATUS_FAIL;
+ goto done;
}
}
+ if (terminator == ';') {
+ // parameter terminator
+ do {
+ char *key = NULL;
+ char *value = NULL;
+
+ // next component must be the parameter key, which must be terminated by mandatory '=', end of the uri is an error
+ // which means checking '=' for key terminator
+ key = tmp;
+ if (!(tmp = strpbrk(tmp, "="))) {
+ ret = KS_STATUS_FAIL;
+ goto done;
+ }
+ *tmp++ = '\0';
+
+ // next component must be the parameter value, which may be terminated by another parameter terminator ';', or the end of the uri
+ // if it is the end of the uri, then the parameter loop will be exited
+ value = tmp;
+ if ((tmp = strpbrk(tmp, ";"))) {
+ *tmp++ = '\0';
+ }
+
+ // create th parameters hash if it does not already exist and add the parameter entry to it, note the key and value are both actually part
+ // of the duplicated uri for components and will be cleaned up with the single string so the hash must not free the key or value itself
+ if (!bi->parameters) ks_hash_create(&bi->parameters, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
+ ks_hash_insert(bi->parameters, (void *)key, (void *)value);
+ } while (tmp);
+ }
+
+done:
+ if (ret != KS_STATUS_SUCCESS) blade_identity_reset(bi);
return KS_STATUS_SUCCESS;
}
-KS_DECLARE(const char *) blade_identity_uri(blade_identity_t *bi)
+KS_DECLARE(const char *) blade_identity_uri_get(blade_identity_t *bi)
{
ks_assert(bi);
return bi->uri;
}
-KS_DECLARE(const char *) blade_identity_parameter_get(blade_identity_t *bi, const char *key)
+KS_DECLARE(const char *) blade_identity_scheme_get(blade_identity_t *bi)
+{
+ ks_assert(bi);
+
+ return bi->scheme;
+}
+
+KS_DECLARE(const char *) blade_identity_user_get(blade_identity_t *bi)
+{
+ ks_assert(bi);
+
+ return bi->user;
+}
+
+KS_DECLARE(const char *) blade_identity_host_get(blade_identity_t *bi)
+{
+ ks_assert(bi);
+
+ return bi->host;
+}
+
+KS_DECLARE(const char *) blade_identity_port_get(blade_identity_t *bi)
+{
+ ks_assert(bi);
+
+ return bi->port;
+}
+
+KS_DECLARE(ks_port_t) blade_identity_portnum_get(blade_identity_t *bi)
+{
+ ks_assert(bi);
+
+ return bi->portnum;
+}
+
+KS_DECLARE(const char *) blade_identity_path_get(blade_identity_t *bi)
+{
+ ks_assert(bi);
+
+ return bi->path;
+}
+
+KS_DECLARE(const char *) blade_identity_parameter_lookup(blade_identity_t *bi, const char *key)
{
ks_assert(bi);
ks_assert(key);
+ if (!bi->parameters) return NULL;
+
return (const char *)ks_hash_search(bi->parameters, (void *)key, KS_UNLOCKED);
}
diff --git a/libs/libblade/src/blade_mastermgr.c b/libs/libblade/src/blade_mastermgr.c
index 61337c98e8..8316216fe8 100644
--- a/libs/libblade/src/blade_mastermgr.c
+++ b/libs/libblade/src/blade_mastermgr.c
@@ -36,10 +36,11 @@
struct blade_mastermgr_s {
blade_handle_t *handle;
+ // @todo use a blade_mastermgr_config_t to store configuration, inline variable, with sane defaults for as much configuration as is possible
+ // then reuse this same pattern across all the manager types that invoke startup configuration processing
const char *master_nodeid;
- // @todo how does "exclusive" play into the controllers, does "exclusive" mean only one provider can exist for a given protocol and realm? what does non exclusive mean?
- ks_hash_t *realms;
- //ks_hash_t *protocols; // protocols that have been published with blade.publish, and the details to locate a protocol controller with blade.locate
+ // @todo how does "exclusive" play into the controllers, does "exclusive" mean only one provider can exist for a given protocol? what does non exclusive mean?
+ ks_hash_t *protocols;
};
@@ -72,8 +73,8 @@ KS_DECLARE(ks_status_t) blade_mastermgr_create(blade_mastermgr_t **bmmgrP, blade
bmmgr = ks_pool_alloc(pool, sizeof(blade_mastermgr_t));
bmmgr->handle = bh;
- ks_hash_create(&bmmgr->realms, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
- ks_assert(bmmgr->realms);
+ ks_hash_create(&bmmgr->protocols, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
+ ks_assert(bmmgr->protocols);
ks_pool_set_cleanup(bmmgr, NULL, blade_mastermgr_cleanup);
@@ -154,20 +155,13 @@ KS_DECLARE(ks_status_t) blade_mastermgr_startup(blade_mastermgr_t *bmmgr, config
}
if (bmmgr->master_nodeid) {
- blade_realm_t *br = NULL;
+ blade_routemgr_local_set(blade_handle_routemgr_get(bmmgr->handle), bmmgr->master_nodeid);
+ blade_routemgr_master_set(blade_handle_routemgr_get(bmmgr->handle), bmmgr->master_nodeid);
- blade_upstreammgr_localid_set(blade_handle_upstreammgr_get(bmmgr->handle), bmmgr->master_nodeid);
- blade_upstreammgr_masterid_set(blade_handle_upstreammgr_get(bmmgr->handle), bmmgr->master_nodeid);
+ blade_mastermgr_protocol_controller_add(bmmgr, "blade.presence", bmmgr->master_nodeid);
- // build the internal blade protocol controlled by the master for the purpose of global event channels for node presence
- blade_realm_create(&br, pool, "blade");
- // @note realm should remain public, these event channels must be available to any node
- blade_mastermgr_realm_add(bmmgr, br);
-
- blade_mastermgr_realm_protocol_controller_add(bmmgr, "blade", "presence", bmmgr->master_nodeid);
-
- blade_mastermgr_realm_protocol_channel_add(bmmgr, "blade", "presence", "join");
- blade_mastermgr_realm_protocol_channel_add(bmmgr, "blade", "presence", "leave");
+ blade_mastermgr_protocol_channel_add(bmmgr, "blade.presence", "join", BLADE_CHANNEL_FLAGS_PUBLIC);
+ blade_mastermgr_protocol_channel_add(bmmgr, "blade.presence", "leave", BLADE_CHANNEL_FLAGS_PUBLIC);
}
return KS_STATUS_SUCCESS;
@@ -188,265 +182,215 @@ KS_DECLARE(ks_status_t) blade_mastermgr_purge(blade_mastermgr_t *bmmgr, const ch
pool = ks_pool_get(bmmgr);
- ks_hash_write_lock(bmmgr->realms);
+ ks_hash_write_lock(bmmgr->protocols);
- for (ks_hash_iterator_t *it = ks_hash_first(bmmgr->realms, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
- const char *realm = NULL;
- blade_realm_t *br = NULL;
- ks_hash_this(it, (const void **)&realm, NULL, (void **)&br);
+ for (ks_hash_iterator_t *it = ks_hash_first(bmmgr->protocols, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
+ const char *protocol = NULL;
+ blade_protocol_t *bp = NULL;
+ ks_bool_t unlock = KS_TRUE;
- blade_realm_write_lock(br);
+ ks_hash_this(it, (const void **)&protocol, NULL, (void **)&bp);
- for (ks_hash_iterator_t *it2 = blade_realm_protocols_iterator(br, KS_UNLOCKED); it2; it2 = ks_hash_next(&it2)) {
+ blade_protocol_write_lock(bp);
+
+ if (blade_protocol_purge(bp, nodeid)) {
+ if (!blade_protocol_controller_available(bp)) {
+ if (!cleanup) ks_hash_create(&cleanup, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
+ ks_hash_insert(cleanup, (void *)protocol, bp);
+ unlock = KS_FALSE;
+ }
+ else {
+ // @todo not the last controller, may need to propagate that the controller is no longer available?
+ }
+ }
+ if (unlock) blade_protocol_write_unlock(bp);
+ }
+
+ if (cleanup) {
+ for (ks_hash_iterator_t *it2 = ks_hash_first(cleanup, KS_UNLOCKED); it2; it2 = ks_hash_next(&it2)) {
const char *protocol = NULL;
blade_protocol_t *bp = NULL;
ks_hash_this(it2, (const void **)&protocol, NULL, (void **)&bp);
- blade_protocol_write_lock(bp);
+ blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE, NULL, protocol, NULL, NULL, NULL, NULL, NULL);
- if (blade_protocol_purge(bp, nodeid)) {
- if (!blade_protocol_controller_available(bp)) {
- if (!cleanup) ks_hash_create(&cleanup, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
- ks_hash_insert(cleanup, (void *)protocol, bp);
- }
- else {
- // @todo not the last controller, may need to propagate that the controller is no longer available?
- }
- }
+ ks_log(KS_LOG_DEBUG, "Protocol Removed: %s\n", protocol);
+ blade_protocol_write_unlock(bp);
+
+ ks_hash_remove(bmmgr->protocols, (void *)protocol);
}
-
- if (cleanup) {
- for (ks_hash_iterator_t *it2 = ks_hash_first(cleanup, KS_UNLOCKED); it2; it2 = ks_hash_next(&it2)) {
- const char *protocol = NULL;
- blade_protocol_t *bp = NULL;
-
- ks_hash_this(it2, (const void **)&protocol, NULL, (void **)&bp);
-
- blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE, NULL, protocol, realm, NULL, NULL, NULL, NULL, NULL);
-
- ks_log(KS_LOG_DEBUG, "Protocol Removed: %s@%s\n", protocol, realm);
- blade_protocol_write_unlock(bp);
- blade_realm_protocol_remove(br, protocol);
- }
- ks_hash_destroy(&cleanup);
- }
-
- blade_realm_write_unlock(br);
+ ks_hash_destroy(&cleanup);
}
- ks_hash_write_unlock(bmmgr->realms);
+ ks_hash_write_unlock(bmmgr->protocols);
return KS_STATUS_SUCCESS;
}
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_add(blade_mastermgr_t *bmmgr, blade_realm_t *realm)
+KS_DECLARE(blade_protocol_t *) blade_mastermgr_protocol_lookup(blade_mastermgr_t *bmmgr, const char *protocol, ks_bool_t writelocked)
{
- ks_assert(bmmgr);
- ks_assert(realm);
-
- ks_log(KS_LOG_DEBUG, "Realm Added: %s\n", blade_realm_name_get(realm));
- ks_hash_insert(bmmgr->realms, (void *)ks_pstrdup(ks_pool_get(bmmgr), blade_realm_name_get(realm)), (void *)realm);
-
- return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_bool_t) blade_mastermgr_realm_remove(blade_mastermgr_t *bmmgr, const char *realm)
-{
- ks_bool_t ret = KS_FALSE;
-
- ks_assert(bmmgr);
- ks_assert(realm);
-
- if (ks_hash_remove(bmmgr->realms, (void *)realm)) {
- ret = KS_TRUE;
- ks_log(KS_LOG_DEBUG, "Realm Removed: %s\n", realm);
- }
-
- return ret;
-}
-
-KS_DECLARE(blade_protocol_t *) blade_mastermgr_realm_protocol_lookup(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, ks_bool_t writelocked)
-{
- blade_realm_t *br = NULL;
blade_protocol_t *bp = NULL;
ks_assert(bmmgr);
ks_assert(protocol);
- ks_assert(realm);
- br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_READLOCKED);
- if (br) bp = blade_realm_protocol_lookup(br, protocol, writelocked);
- ks_hash_read_unlock(bmmgr->realms);
+ bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_READLOCKED);
+ if (bp) {
+ if (writelocked) blade_protocol_write_lock(bp);
+ else blade_protocol_read_lock(bp);
+ }
+ ks_hash_read_unlock(bmmgr->protocols);
return bp;
}
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_controller_add(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *controller)
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_controller_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *controller)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_pool_t *pool = NULL;
- blade_realm_t *br = NULL;
blade_protocol_t *bp = NULL;
ks_assert(bmmgr);
- ks_assert(realm);
ks_assert(protocol);
ks_assert(controller);
pool = ks_pool_get(bmmgr);
- ks_hash_read_lock(bmmgr->realms);
+ ks_hash_write_lock(bmmgr->protocols);
- br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
- if (!br) {
- ret = KS_STATUS_FAIL;
- goto done;
- }
+ bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
- bp = blade_realm_protocol_lookup(br, protocol, KS_TRUE);
- if (bp) {
- // @todo deal with exclusive stuff when the protocol is already registered
- }
-
- if (!bp) {
- blade_protocol_create(&bp, pool, br, protocol);
+ if (bp) blade_protocol_write_lock(bp);
+ else {
+ blade_protocol_create(&bp, pool, protocol);
ks_assert(bp);
blade_protocol_write_lock(bp);
- ks_log(KS_LOG_DEBUG, "Protocol Added: %s@%s\n", protocol, realm);
- blade_realm_protocol_add(br, bp);
+ ks_log(KS_LOG_DEBUG, "Protocol Added: %s\n", protocol);
+ ks_hash_insert(bmmgr->protocols, (void *)ks_pstrdup(ks_pool_get(bmmgr), protocol), (void *)bp);
}
blade_protocol_controller_add(bp, controller);
+ ks_log(KS_LOG_DEBUG, "Protocol Controller Added: %s to %s\n", controller, protocol);
+
blade_protocol_write_unlock(bp);
-done:
- ks_hash_read_unlock(bmmgr->realms);
+ ks_hash_write_unlock(bmmgr->protocols);
return ret;
}
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_controller_remove(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *controller)
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_controller_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *controller)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_pool_t *pool = NULL;
- blade_realm_t *br = NULL;
blade_protocol_t *bp = NULL;
+ ks_bool_t remove = KS_FALSE;
ks_assert(bmmgr);
- ks_assert(realm);
ks_assert(protocol);
ks_assert(controller);
pool = ks_pool_get(bmmgr);
- ks_hash_read_lock(bmmgr->realms);
+ ks_hash_write_lock(bmmgr->protocols);
- br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
- if (!br) {
- ret = KS_STATUS_FAIL;
- goto done;
- }
-
- bp = blade_realm_protocol_lookup(br, protocol, KS_TRUE);
- if (bp) {
- if (blade_protocol_controller_remove(bp, controller)) {
- if (!blade_protocol_controller_available(bp)) {
- blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE, NULL, protocol, realm, NULL, NULL, NULL, NULL, NULL);
-
- ks_log(KS_LOG_DEBUG, "Protocol Removed: %s@%s\n", protocol, realm);
- blade_realm_protocol_remove(br, protocol);
- } else {
- // @todo not the last controller, may need to propagate when a specific controller becomes unavailable though
- }
- }
- blade_protocol_write_unlock(bp);
- }
-
-done:
- ks_hash_read_unlock(bmmgr->realms);
-
- return ret;
-}
-
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_channel_add(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *channel)
-{
- ks_status_t ret = KS_STATUS_SUCCESS;
- blade_realm_t *br = NULL;
- blade_protocol_t *bp = NULL;
- blade_channel_t *bc = NULL;
-
- ks_assert(bmmgr);
- ks_assert(realm);
- ks_assert(protocol);
- ks_assert(channel);
-
- ks_hash_read_lock(bmmgr->realms);
-
- br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
- if (!br) {
- ret = KS_STATUS_FAIL;
- goto done;
- }
-
- bp = blade_realm_protocol_lookup(br, protocol, KS_TRUE);
+ bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (!bp) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
+ blade_protocol_write_lock(bp);
+
+ if (blade_protocol_controller_remove(bp, controller)) {
+ ks_log(KS_LOG_DEBUG, "Protocol Controller Removed: %s from %s\n", controller, protocol);
+ if (!blade_protocol_controller_available(bp)) {
+ blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE, NULL, protocol, NULL, NULL, NULL, NULL, NULL);
+
+ ks_log(KS_LOG_DEBUG, "Protocol Removed: %s\n", protocol);
+ remove = KS_TRUE;
+ } else {
+ // @todo not the last controller, may need to propagate when a specific controller becomes unavailable though
+ }
+ }
+
+ blade_protocol_write_unlock(bp);
+
+ if (remove) ks_hash_remove(bmmgr->protocols, (void *)protocol);
+
+done:
+ ks_hash_write_unlock(bmmgr->protocols);
+
+ return ret;
+}
+
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel, blade_channel_flags_t flags)
+{
+ ks_status_t ret = KS_STATUS_SUCCESS;
+ blade_protocol_t *bp = NULL;
+ blade_channel_t *bc = NULL;
+
+ ks_assert(bmmgr);
+ ks_assert(protocol);
+ ks_assert(channel);
+
+ ks_hash_read_lock(bmmgr->protocols);
+
+ bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
+ if (!bp) {
+ ret = KS_STATUS_NOT_FOUND;
+ goto done;
+ }
+
+ blade_protocol_write_lock(bp);
+
bc = blade_protocol_channel_lookup(bp, channel, KS_TRUE);
- if (!bc) {
+ if (bc) {
ret = KS_STATUS_DUPLICATE_OPERATION;
goto done;
}
- blade_channel_create(&bc, ks_pool_get(bc), channel);
+ blade_channel_create(&bc, ks_pool_get(bp), channel, flags);
ks_assert(bc);
blade_channel_write_lock(bc);
if (blade_protocol_channel_add(bp, bc) == KS_STATUS_SUCCESS) {
- ks_log(KS_LOG_DEBUG, "Protocol Channel Added: %s@%s/%s\n", blade_protocol_name_get(bp), blade_realm_name_get(br), blade_channel_name_get(bc));
+ ks_log(KS_LOG_DEBUG, "Protocol Channel Added: %s to %s\n", blade_channel_name_get(bc), blade_protocol_name_get(bp));
}
done:
if (bc) blade_channel_write_unlock(bc);
if (bp) blade_protocol_write_unlock(bp);
- ks_hash_read_unlock(bmmgr->realms);
+ ks_hash_read_unlock(bmmgr->protocols);
return ret;
}
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_channel_remove(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *channel)
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel)
{
ks_status_t ret = KS_STATUS_SUCCESS;
- blade_realm_t *br = NULL;
blade_protocol_t *bp = NULL;
blade_channel_t *bc = NULL;
ks_assert(bmmgr);
- ks_assert(realm);
ks_assert(protocol);
ks_assert(channel);
- ks_hash_read_lock(bmmgr->realms);
+ ks_hash_read_lock(bmmgr->protocols);
- br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
- if (!br) {
- ret = KS_STATUS_FAIL;
- goto done;
- }
-
- bp = blade_realm_protocol_lookup(br, protocol, KS_TRUE);
+ bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (!bp) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
+ blade_protocol_write_lock(bp);
+
bc = blade_protocol_channel_lookup(bp, channel, KS_TRUE);
if (!bc) {
ret = KS_STATUS_NOT_FOUND;
@@ -454,47 +398,41 @@ KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_channel_remove(blade_mast
}
if (blade_protocol_channel_remove(bp, channel)) {
- blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_CHANNEL_REMOVE, NULL, protocol, realm, channel, NULL, NULL, NULL, NULL);
- ks_log(KS_LOG_DEBUG, "Protocol Channel Removed: %s@%s/%s\n", blade_protocol_name_get(bp), blade_realm_name_get(br), blade_channel_name_get(bc));
+ blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_CHANNEL_REMOVE, NULL, protocol, channel, NULL, NULL, NULL, NULL);
+ ks_log(KS_LOG_DEBUG, "Protocol Channel Removed: %s from %s\n", blade_channel_name_get(bc), blade_protocol_name_get(bp));
blade_channel_write_unlock(bc);
blade_channel_destroy(&bc);
}
done:
if (bp) blade_protocol_write_unlock(bp);
- ks_hash_read_unlock(bmmgr->realms);
+ ks_hash_read_unlock(bmmgr->protocols);
return ret;
}
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_channel_authorize(blade_mastermgr_t *bmmgr, ks_bool_t remove, const char *realm, const char *protocol, const char *channel, const char *controller, const char *target)
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_authorize(blade_mastermgr_t *bmmgr, ks_bool_t remove, const char *protocol, const char *channel, const char *controller, const char *target)
{
ks_status_t ret = KS_STATUS_SUCCESS;
- blade_realm_t *br = NULL;
blade_protocol_t *bp = NULL;
blade_channel_t *bc = NULL;
ks_assert(bmmgr);
- ks_assert(realm);
ks_assert(protocol);
ks_assert(channel);
ks_assert(controller);
ks_assert(target);
- ks_hash_read_lock(bmmgr->realms);
+ ks_hash_read_lock(bmmgr->protocols);
- br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
- if (!br) {
- ret = KS_STATUS_FAIL;
- goto done;
- }
-
- bp = blade_realm_protocol_lookup(br, protocol, KS_FALSE);
+ bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (!bp) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
+ blade_protocol_read_lock(bp);
+
if (!blade_protocol_controller_verify(bp, controller)) {
ret = KS_STATUS_NOT_ALLOWED;
goto done;
@@ -508,63 +446,56 @@ KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_channel_authorize(blade_m
if (remove) {
if (blade_channel_authorization_remove(bc, target)) {
- ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Removed: %s from %s@%s/%s\n", target, blade_protocol_name_get(bp), blade_realm_name_get(br), blade_channel_name_get(bc));
+ ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Removed: %s from protocol %s, channel %s\n", target, blade_protocol_name_get(bp), blade_channel_name_get(bc));
} else ret = KS_STATUS_NOT_FOUND;
} else {
if (blade_channel_authorization_add(bc, target)) {
- ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Added: %s to %s@%s/%s\n", target, blade_protocol_name_get(bp), blade_realm_name_get(br), blade_channel_name_get(bc));
+ ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Added: %s to protocol %s, channel %s\n", target, blade_protocol_name_get(bp), blade_channel_name_get(bc));
}
}
done:
if (bc) blade_channel_write_unlock(bc);
if (bp) blade_protocol_read_unlock(bp);
- ks_hash_read_unlock(bmmgr->realms);
+ ks_hash_read_unlock(bmmgr->protocols);
return ret;
}
-KS_DECLARE(ks_bool_t) blade_mastermgr_realm_protocol_channel_authorization_verify(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *channel, const char *target)
+KS_DECLARE(ks_bool_t) blade_mastermgr_protocol_channel_authorization_verify(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel, const char *target)
{
ks_bool_t ret = KS_FALSE;
- blade_realm_t *br = NULL;
blade_protocol_t *bp = NULL;
blade_channel_t *bc = NULL;
ks_assert(bmmgr);
- ks_assert(realm);
ks_assert(protocol);
ks_assert(channel);
ks_assert(target);
- ks_hash_read_lock(bmmgr->realms);
+ ks_hash_read_lock(bmmgr->protocols);
- br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
- if (!br) {
- ret = KS_STATUS_FAIL;
- goto done;
- }
-
- bp = blade_realm_protocol_lookup(br, protocol, KS_FALSE);
+ bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
if (!bp) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
+ blade_protocol_read_lock(bp);
+
bc = blade_protocol_channel_lookup(bp, channel, KS_FALSE);
if (!bc) {
ret = KS_STATUS_NOT_FOUND;
goto done;
}
- ret = blade_channel_authorization_verify(bc, target);
-
- blade_protocol_read_unlock(bp);
+ if ((blade_channel_flags_get(bc) & BLADE_CHANNEL_FLAGS_PUBLIC) == BLADE_CHANNEL_FLAGS_PUBLIC) ret = KS_TRUE;
+ else ret = blade_channel_authorization_verify(bc, target);
done:
if (bc) blade_channel_read_unlock(bc);
if (bp) blade_protocol_read_unlock(bp);
- ks_hash_read_unlock(bmmgr->realms);
+ ks_hash_read_unlock(bmmgr->protocols);
return ret;
}
diff --git a/libs/libblade/src/blade_protocol.c b/libs/libblade/src/blade_protocol.c
index 79efbf1895..d27840166c 100644
--- a/libs/libblade/src/blade_protocol.c
+++ b/libs/libblade/src/blade_protocol.c
@@ -34,7 +34,6 @@
#include "blade.h"
struct blade_protocol_s {
- blade_realm_t *realm;
const char *name;
ks_rwl_t *lock;
ks_hash_t *controllers;
@@ -63,17 +62,15 @@ static void blade_protocol_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_
}
}
-KS_DECLARE(ks_status_t) blade_protocol_create(blade_protocol_t **bpP, ks_pool_t *pool, blade_realm_t *realm, const char *name)
+KS_DECLARE(ks_status_t) blade_protocol_create(blade_protocol_t **bpP, ks_pool_t *pool, const char *name)
{
blade_protocol_t *bp = NULL;
ks_assert(bpP);
ks_assert(pool);
- ks_assert(realm);
ks_assert(name);
bp = ks_pool_alloc(pool, sizeof(blade_protocol_t));
- bp->realm = realm;
bp->name = ks_pstrdup(pool, name);
ks_rwl_create(&bp->lock, pool);
@@ -102,12 +99,6 @@ KS_DECLARE(ks_status_t) blade_protocol_destroy(blade_protocol_t **bpP)
return KS_STATUS_SUCCESS;
}
-KS_DECLARE(blade_realm_t *) blade_protocol_realm_get(blade_protocol_t *bp)
-{
- ks_assert(bp);
- return bp->realm;
-}
-
KS_DECLARE(const char *) blade_protocol_name_get(blade_protocol_t *bp)
{
ks_assert(bp);
@@ -140,6 +131,7 @@ KS_DECLARE(ks_status_t) blade_protocol_write_unlock(blade_protocol_t *bp)
KS_DECLARE(ks_bool_t) blade_protocol_purge(blade_protocol_t *bp, const char *nodeid)
{
+ ks_bool_t ret = KS_FALSE;
ks_assert(bp);
ks_assert(nodeid);
@@ -147,17 +139,21 @@ KS_DECLARE(ks_bool_t) blade_protocol_purge(blade_protocol_t *bp, const char *nod
ks_hash_write_lock(bp->channels);
for (ks_hash_iterator_t *it = ks_hash_first(bp->channels, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
const char *key = NULL;
- ks_hash_t *authorizations = NULL;
+ blade_channel_t *channel = NULL;
- ks_hash_this(it, (const void **)&key, NULL, (void **)&authorizations);
+ ks_hash_this(it, (const void **)&key, NULL, (void **)&channel);
- if (ks_hash_remove(authorizations, (void *)nodeid)) {
- ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Removed: %s from %s@%s/%s\n", nodeid, bp->name, blade_realm_name_get(bp->realm), key);
+ if (blade_channel_authorization_remove(channel, nodeid)) {
+ ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Removed: %s from protocol %s, channel %s\n", nodeid, bp->name, key);
}
}
ks_hash_write_unlock(bp->channels);
- return blade_protocol_controller_remove(bp, nodeid);
+ if ((ret = blade_protocol_controller_remove(bp, nodeid))) {
+ ks_log(KS_LOG_DEBUG, "Protocol Controller Removed: %s from %s\n", nodeid, bp->name);
+ }
+
+ return ret;
}
KS_DECLARE(cJSON *) blade_protocol_controller_pack(blade_protocol_t *bp)
@@ -203,8 +199,6 @@ KS_DECLARE(ks_status_t) blade_protocol_controller_add(blade_protocol_t *bp, cons
key = ks_pstrdup(ks_pool_get(bp), nodeid);
ks_hash_insert(bp->controllers, (void *)key, (void *)KS_TRUE);
- ks_log(KS_LOG_DEBUG, "Protocol Controller Added: %s to %s@%s\n", nodeid, bp->name, blade_realm_name_get(bp->realm));
-
return KS_STATUS_SUCCESS;
}
@@ -218,7 +212,6 @@ KS_DECLARE(ks_bool_t) blade_protocol_controller_remove(blade_protocol_t *bp, con
ks_hash_write_lock(bp->controllers);
if (ks_hash_remove(bp->controllers, (void *)nodeid)) {
ret = KS_TRUE;
- ks_log(KS_LOG_DEBUG, "Protocol Controller Removed: %s from %s@%s\n", nodeid, bp->name, blade_realm_name_get(bp->realm));
}
ks_hash_write_unlock(bp->controllers);
diff --git a/libs/libblade/src/blade_realm.c b/libs/libblade/src/blade_realm.c
deleted file mode 100644
index 149b57e66e..0000000000
--- a/libs/libblade/src/blade_realm.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2017, Shane Bryldt
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "blade.h"
-
-struct blade_realm_s {
- const char *name;
- ks_rwl_t *lock;
- ks_hash_t *protocols;
-};
-
-
-static void blade_realm_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
-{
- blade_realm_t *br = (blade_realm_t *)ptr;
-
- ks_assert(br);
-
- switch (action) {
- case KS_MPCL_ANNOUNCE:
- break;
- case KS_MPCL_TEARDOWN:
- if (br->name) ks_pool_free(&br->name);
- if (br->lock) ks_rwl_destroy(&br->lock);
- if (br->protocols) ks_hash_destroy(&br->protocols);
- break;
- case KS_MPCL_DESTROY:
- break;
- }
-}
-
-KS_DECLARE(ks_status_t) blade_realm_create(blade_realm_t **brP, ks_pool_t *pool, const char *name)
-{
- blade_realm_t *br = NULL;
-
- ks_assert(brP);
- ks_assert(pool);
- ks_assert(name);
-
- br = ks_pool_alloc(pool, sizeof(blade_realm_t));
- br->name = ks_pstrdup(pool, name);
-
- ks_rwl_create(&br->lock, pool);
- ks_assert(br->lock);
-
- ks_hash_create(&br->protocols, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
- ks_assert(br->protocols);
-
- ks_pool_set_cleanup(br, NULL, blade_realm_cleanup);
-
- *brP = br;
-
- return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_realm_destroy(blade_realm_t **brP)
-{
- ks_assert(brP);
- ks_assert(*brP);
-
- ks_pool_free(brP);
-
- return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(const char *) blade_realm_name_get(blade_realm_t *br)
-{
- ks_assert(br);
- return br->name;
-}
-
-KS_DECLARE(ks_status_t) blade_realm_read_lock(blade_realm_t *br)
-{
- ks_assert(br);
- return ks_rwl_read_lock(br->lock);
-}
-
-KS_DECLARE(ks_status_t) blade_realm_read_unlock(blade_realm_t *br)
-{
- ks_assert(br);
- return ks_rwl_read_unlock(br->lock);
-}
-
-KS_DECLARE(ks_status_t) blade_realm_write_lock(blade_realm_t *br)
-{
- ks_assert(br);
- return ks_rwl_write_lock(br->lock);
-}
-
-KS_DECLARE(ks_status_t) blade_realm_write_unlock(blade_realm_t *br)
-{
- ks_assert(br);
- return ks_rwl_write_unlock(br->lock);
-}
-
-KS_DECLARE(ks_hash_iterator_t *) blade_realm_protocols_iterator(blade_realm_t *br, ks_locked_t locked)
-{
- ks_assert(br);
- return ks_hash_first(br->protocols, locked);
-}
-
-KS_DECLARE(blade_protocol_t *) blade_realm_protocol_lookup(blade_realm_t *br, const char *protocol, ks_bool_t writelocked)
-{
- blade_protocol_t *bp = NULL;
-
- ks_assert(br);
- ks_assert(protocol);
-
- bp = (blade_protocol_t *)ks_hash_search(br->protocols, (void *)protocol, KS_READLOCKED);
- if (bp) {
- if (writelocked) blade_protocol_write_lock(bp);
- else blade_protocol_read_lock(bp);
- }
- ks_hash_read_unlock(br->protocols);
-
- return bp;
-}
-
-KS_DECLARE(ks_status_t) blade_realm_protocol_add(blade_realm_t *br, blade_protocol_t *protocol)
-{
- ks_assert(br);
- ks_assert(protocol);
-
- ks_hash_insert(br->protocols, (void *)ks_pstrdup(ks_pool_get(br), blade_protocol_name_get(protocol)), (void *)protocol);
-
- return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_realm_protocol_remove(blade_realm_t *br, const char *protocol)
-{
- ks_assert(br);
- ks_assert(protocol);
-
- ks_hash_remove(br->protocols, (void *)protocol);
-
- return KS_STATUS_SUCCESS;
-}
-
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
- */
diff --git a/libs/libblade/src/blade_routemgr.c b/libs/libblade/src/blade_routemgr.c
index 277908a599..3b1eeb4cf9 100644
--- a/libs/libblade/src/blade_routemgr.c
+++ b/libs/libblade/src/blade_routemgr.c
@@ -36,7 +36,14 @@
struct blade_routemgr_s {
blade_handle_t *handle;
- ks_hash_t *routes; // id, id
+ const char *local_nodeid;
+ ks_rwl_t *local_lock;
+
+ const char *master_nodeid;
+ ks_rwl_t *master_lock;
+
+ ks_hash_t *routes; // target nodeid, downstream router nodeid
+ ks_hash_t *identities; // identity, target nodeid
};
@@ -69,10 +76,19 @@ KS_DECLARE(ks_status_t) blade_routemgr_create(blade_routemgr_t **brmgrP, blade_h
brmgr = ks_pool_alloc(pool, sizeof(blade_routemgr_t));
brmgr->handle = bh;
- // @note can let removes free keys and values for routes, both are strings and allocated from the same pool as the hash itself
+ ks_rwl_create(&brmgr->local_lock, pool);
+ ks_assert(brmgr->local_lock);
+
+ ks_rwl_create(&brmgr->master_lock, pool);
+ ks_assert(brmgr->master_lock);
+
+ // @note can let removes free keys and values for routes and identity, both use keys and values that are strings allocated from the same pool as the hash itself
ks_hash_create(&brmgr->routes, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
ks_assert(brmgr->routes);
+ ks_hash_create(&brmgr->identities, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
+ ks_assert(brmgr->routes);
+
ks_pool_set_cleanup(brmgr, NULL, blade_routemgr_cleanup);
*brmgrP = brmgr;
@@ -105,6 +121,206 @@ KS_DECLARE(blade_handle_t *) blade_routemgr_handle_get(blade_routemgr_t *brmgr)
return brmgr->handle;
}
+KS_DECLARE(ks_status_t) blade_routemgr_local_set(blade_routemgr_t *brmgr, const char *nodeid)
+{
+ ks_status_t ret = KS_STATUS_SUCCESS;
+
+ ks_assert(brmgr);
+
+ ks_rwl_write_lock(brmgr->local_lock);
+
+ if (brmgr->local_nodeid) {
+ ret = KS_STATUS_DUPLICATE_OPERATION;
+ goto done;
+ }
+ if (nodeid) brmgr->local_nodeid = ks_pstrdup(ks_pool_get(brmgr), nodeid);
+
+ ks_log(KS_LOG_DEBUG, "Local NodeID: %s\n", nodeid);
+
+done:
+ ks_rwl_write_unlock(brmgr->local_lock);
+
+ return ret;
+}
+
+KS_DECLARE(ks_bool_t) blade_routemgr_local_check(blade_routemgr_t *brmgr, const char *target)
+{
+ ks_bool_t ret = KS_FALSE;
+
+ ks_assert(brmgr);
+ ks_assert(target);
+
+ ks_rwl_read_lock(brmgr->local_lock);
+
+ ret = !ks_safe_strcasecmp(brmgr->local_nodeid, target);
+
+ if (!ret) {
+ // @todo must parse target to an identity, and back to a properly formatted identity key
+ blade_identity_t *identity = NULL;
+ ks_pool_t *pool = ks_pool_get(brmgr);
+
+ blade_identity_create(&identity, pool);
+ if (blade_identity_parse(identity, target) == KS_STATUS_SUCCESS) {
+ char *key = ks_psprintf(pool, "%s@%s/%s", blade_identity_user_get(identity), blade_identity_host_get(identity), blade_identity_path_get(identity));
+ const char *value = (const char *)ks_hash_search(brmgr->identities, (void *)key, KS_READLOCKED);
+
+ if (value) ret = !ks_safe_strcasecmp(brmgr->local_nodeid, value);
+
+ ks_hash_read_unlock(brmgr->identities);
+
+ ks_pool_free(&key);
+ }
+
+ blade_identity_destroy(&identity);
+ }
+
+ ks_rwl_read_unlock(brmgr->local_lock);
+
+ return ret;
+}
+
+KS_DECLARE(ks_bool_t) blade_routemgr_local_copy(blade_routemgr_t *brmgr, const char **nodeid)
+{
+ ks_bool_t ret = KS_FALSE;
+
+ ks_assert(brmgr);
+ ks_assert(nodeid);
+
+ *nodeid = NULL;
+
+ ks_rwl_read_lock(brmgr->local_lock);
+
+ if (brmgr->local_nodeid) {
+ ret = KS_TRUE;
+ *nodeid = ks_pstrdup(ks_pool_get(brmgr), brmgr->local_nodeid);
+ }
+
+ ks_rwl_read_unlock(brmgr->local_lock);
+
+ return ret;
+}
+
+KS_DECLARE(ks_bool_t) blade_routemgr_local_pack(blade_routemgr_t *brmgr, cJSON *json, const char *key)
+{
+ ks_bool_t ret = KS_FALSE;
+
+ ks_assert(brmgr);
+ ks_assert(json);
+ ks_assert(key);
+
+ ks_rwl_read_lock(brmgr->local_lock);
+
+ if (brmgr->local_nodeid) {
+ ret = KS_TRUE;
+ cJSON_AddStringToObject(json, key, brmgr->local_nodeid);
+ }
+
+ ks_rwl_read_unlock(brmgr->local_lock);
+
+ return ret;
+}
+
+KS_DECLARE(blade_session_t *) blade_routemgr_upstream_lookup(blade_routemgr_t *brmgr)
+{
+ blade_session_t *bs = NULL;
+
+ ks_assert(brmgr);
+
+ ks_rwl_read_lock(brmgr->local_lock);
+
+ if (brmgr->local_nodeid) bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(brmgr->handle), brmgr->local_nodeid);
+
+ ks_rwl_read_unlock(brmgr->local_lock);
+
+ return bs;
+}
+
+KS_DECLARE(ks_status_t) blade_routemgr_master_set(blade_routemgr_t *brmgr, const char *nodeid)
+{
+ ks_assert(brmgr);
+
+ ks_rwl_write_lock(brmgr->master_lock);
+
+ if (brmgr->master_nodeid) ks_pool_free(&brmgr->master_nodeid);
+ if (nodeid) brmgr->master_nodeid = ks_pstrdup(ks_pool_get(brmgr), nodeid);
+
+ ks_rwl_write_unlock(brmgr->master_lock);
+
+ ks_log(KS_LOG_DEBUG, "Master NodeID: %s\n", nodeid);
+
+ return KS_STATUS_SUCCESS;
+}
+
+KS_DECLARE(ks_bool_t) blade_routemgr_master_check(blade_routemgr_t *brmgr, const char *target)
+{
+ ks_bool_t ret = KS_FALSE;
+
+ ks_assert(brmgr);
+ ks_assert(target);
+
+ ks_rwl_read_lock(brmgr->master_lock);
+
+ ret = ks_safe_strcasecmp(brmgr->master_nodeid, target) == 0;
+
+ // @todo may also need to check against master identities, there are a number of ways master identities
+ // could be propagated to ensure this check works for identities, but for now just assume that master cannot
+ // use identities for these checks which should generally only be done to validate certain blade CoreRPC's which
+ // expect the responder to be the master, and which get packed in the function below
+ // the following would only work on the master itself, where it registered it's own identities and thus has the
+ // identities in the identities mapping, other nodes do not see master identity registrations and cannot currently
+ // validate master identities
+ //if (!ret) {
+ // const char *nodeid = (const char *)ks_hash_search(brmgr->identities, (void *)target, KS_READLOCKED);
+ // ret = nodeid && !ks_safe_strcasecmp(nodeid, brmgr->master_nodeid);
+ // ks_hash_read_unlock(brmgr->identities);
+ //}
+
+ ks_rwl_read_unlock(brmgr->master_lock);
+
+ return ret;
+}
+
+KS_DECLARE(ks_bool_t) blade_routemgr_master_pack(blade_routemgr_t *brmgr, cJSON *json, const char *key)
+{
+ ks_bool_t ret = KS_FALSE;
+
+ ks_assert(brmgr);
+ ks_assert(json);
+ ks_assert(key);
+
+ ks_rwl_read_lock(brmgr->master_lock);
+
+ if (brmgr->master_nodeid) {
+ ret = KS_TRUE;
+ cJSON_AddStringToObject(json, key, brmgr->master_nodeid);
+ // @todo may need to pack master identities into the json as well, for now just use nodeid only and
+ // assume master nodes have no identities, however this call is primarily used only to force certain
+ // blade CoreRPC's to route to the known master node, but is also used to pass to downstream nodes
+ // when they connect
+ }
+
+ ks_rwl_read_unlock(brmgr->master_lock);
+
+ return ret;
+}
+
+KS_DECLARE(ks_bool_t) blade_routemgr_master_local(blade_routemgr_t *brmgr)
+{
+ ks_bool_t ret = KS_FALSE;
+
+ ks_assert(brmgr);
+
+ ks_rwl_read_lock(brmgr->master_lock);
+
+ ret = brmgr->master_nodeid && brmgr->local_nodeid && !ks_safe_strcasecmp(brmgr->master_nodeid, brmgr->local_nodeid);
+
+ //ret = brmgr->master_nodeid && brmgr->localid && !ks_safe_strcasecmp(brmgr->master_nodeid, brmgr->local_nodeid);
+
+ ks_rwl_read_unlock(brmgr->master_lock);
+
+ return ret;
+}
+
KS_DECLARE(blade_session_t *) blade_routemgr_route_lookup(blade_routemgr_t *brmgr, const char *target)
{
blade_session_t *bs = NULL;
@@ -114,12 +330,74 @@ KS_DECLARE(blade_session_t *) blade_routemgr_route_lookup(blade_routemgr_t *brmg
ks_assert(target);
router = (const char *)ks_hash_search(brmgr->routes, (void *)target, KS_READLOCKED);
+ if (!router) {
+ // @todo this is all really inefficient, but we need the string to be parsed and recombined to ensure correctness for key matching
+ blade_identity_t *identity = NULL;
+ ks_pool_t *pool = ks_pool_get(brmgr);
+
+ blade_identity_create(&identity, pool);
+ if (blade_identity_parse(identity, target) == KS_STATUS_SUCCESS) {
+ char *key = ks_psprintf(pool, "%s@%s/%s", blade_identity_user_get(identity), blade_identity_host_get(identity), blade_identity_path_get(identity));
+
+ router = (const char *)ks_hash_search(brmgr->identities, (void *)key, KS_READLOCKED);
+ ks_hash_read_unlock(brmgr->identities);
+
+ ks_pool_free(&key);
+ }
+
+ blade_identity_destroy(&identity);
+ }
if (router) bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(brmgr->handle), router);
ks_hash_read_unlock(brmgr->routes);
return bs;
}
+ks_status_t blade_routemgr_purge(blade_routemgr_t *brmgr, const char *target)
+{
+ ks_hash_t* cleanup = NULL;
+
+ ks_assert(brmgr);
+ ks_assert(target);
+
+ // @note this approach is deliberately slower than it could be, as it ensures that if there is a race condition and another session has registered
+ // the same identity before a prior session times out, then the correct targetted random nodeid is matched to confirm the identity removal and will
+ // not remove if the target isn't what is expected
+
+ ks_hash_write_lock(brmgr->identities);
+
+ for (ks_hash_iterator_t *it = ks_hash_first(brmgr->identities, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
+ const char *key = NULL;
+ const char *value = NULL;
+
+ ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
+
+ if (value && !ks_safe_strcasecmp(value, target)) {
+ if (!cleanup) ks_hash_create(&cleanup, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, ks_pool_get(brmgr));
+ ks_hash_insert(cleanup, (const void *)key, (void *)value);
+ }
+ }
+
+ if (cleanup) {
+ for (ks_hash_iterator_t *it = ks_hash_first(cleanup, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
+ const char *key = NULL;
+ const char *value = NULL;
+
+ ks_hash_this(it, (const void **)&key, NULL, (void **)&value);
+
+ ks_log(KS_LOG_DEBUG, "Identity Removed: %s through %s\n", key, value);
+
+ ks_hash_remove(brmgr->identities, (void *)key);
+ }
+ }
+
+ ks_hash_write_unlock(brmgr->identities);
+
+ if (cleanup) ks_hash_destroy(&cleanup);
+
+ return KS_STATUS_SUCCESS;
+}
+
KS_DECLARE(ks_status_t) blade_routemgr_route_add(blade_routemgr_t *brmgr, const char *target, const char *router)
{
ks_pool_t *pool = NULL;
@@ -139,17 +417,16 @@ KS_DECLARE(ks_status_t) blade_routemgr_route_add(blade_routemgr_t *brmgr, const
ks_log(KS_LOG_DEBUG, "Route Added: %s through %s\n", key, value);
- blade_handle_rpcregister(brmgr->handle, target, KS_FALSE, NULL, NULL);
+ blade_handle_rpcroute(brmgr->handle, target, KS_FALSE, NULL, NULL);
- if (blade_upstreammgr_masterlocal(blade_handle_upstreammgr_get(brmgr->handle))) {
+ if (blade_routemgr_master_local(brmgr)) {
cJSON *params = cJSON_CreateObject();
cJSON_AddStringToObject(params, "nodeid", target);
- blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "presence", "blade", "join", "joined", params, NULL, NULL);
+ blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "blade.presence", "join", "joined", params, NULL, NULL);
cJSON_Delete(params);
}
return KS_STATUS_SUCCESS;
-
}
KS_DECLARE(ks_status_t) blade_routemgr_route_remove(blade_routemgr_t *brmgr, const char *target)
@@ -161,7 +438,7 @@ KS_DECLARE(ks_status_t) blade_routemgr_route_remove(blade_routemgr_t *brmgr, con
ks_log(KS_LOG_DEBUG, "Route Removed: %s\n", target);
- blade_handle_rpcregister(brmgr->handle, target, KS_TRUE, NULL, NULL);
+ blade_handle_rpcroute(brmgr->handle, target, KS_TRUE, NULL, NULL);
blade_subscriptionmgr_purge(blade_handle_subscriptionmgr_get(brmgr->handle), target);
@@ -172,16 +449,88 @@ KS_DECLARE(ks_status_t) blade_routemgr_route_remove(blade_routemgr_t *brmgr, con
blade_mastermgr_purge(blade_handle_mastermgr_get(brmgr->handle), target);
- if (blade_upstreammgr_masterlocal(blade_handle_upstreammgr_get(brmgr->handle))) {
+ blade_routemgr_purge(brmgr, target);
+
+ if (blade_routemgr_master_local(brmgr)) {
cJSON *params = cJSON_CreateObject();
cJSON_AddStringToObject(params, "nodeid", target);
- blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "presence", "blade", "leave", "left", params, NULL, NULL);
+ blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "blade.presence", "leave", "left", params, NULL, NULL);
cJSON_Delete(params);
}
return KS_STATUS_SUCCESS;
}
+KS_DECLARE(ks_status_t) blade_routemgr_identity_add(blade_routemgr_t *brmgr, blade_identity_t *identity, const char *target)
+{
+ ks_pool_t *pool = NULL;
+ char *key = NULL;
+ char *value = NULL;
+
+ ks_assert(brmgr);
+ ks_assert(identity);
+ ks_assert(target);
+
+ pool = ks_pool_get(brmgr);
+
+ key = ks_psprintf(pool, "%s@%s/%s", blade_identity_user_get(identity), blade_identity_host_get(identity), blade_identity_path_get(identity));
+ value = ks_pstrdup(pool, target);
+
+ ks_hash_insert(brmgr->identities, (void *)key, (void *)value);
+
+ ks_log(KS_LOG_DEBUG, "Identity Added: %s through %s\n", key, value);
+
+ //if (blade_routemgr_master_local(blade_handle_routemgr_get(brmgr->handle))) {
+ // cJSON *params = cJSON_CreateObject();
+ // cJSON_AddStringToObject(params, "identity", blade_identity_uri_get(identity)); // full identity uri string
+ // cJSON_AddStringToObject(params, "nodeid", target);
+ // blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "blade.presence", "join", "joined", params, NULL, NULL);
+ // cJSON_Delete(params);
+ //}
+
+ return KS_STATUS_SUCCESS;
+}
+
+KS_DECLARE(ks_status_t) blade_routemgr_identity_remove(blade_routemgr_t *brmgr, blade_identity_t *identity, const char *target)
+{
+ ks_pool_t *pool = NULL;
+ char *key = NULL;
+ const char *value = NULL;
+
+ ks_assert(brmgr);
+ ks_assert(identity);
+ ks_assert(target);
+
+ pool = ks_pool_get(brmgr);
+
+ key = ks_psprintf(pool, "%s@%s/%s", blade_identity_user_get(identity), blade_identity_host_get(identity), blade_identity_path_get(identity));
+
+ // @note this approach is deliberately slower than it could be, as it ensures that if there is a race condition and another session has registered
+ // the same identity before a prior session times out, then the correct targetted random nodeid is matched to confirm the identity removal and will
+ // not remove if the target isn't what is expected
+
+ ks_hash_write_lock(brmgr->identities);
+
+ value = (const char *)ks_hash_search(brmgr->identities, (void *)key, KS_UNLOCKED);
+
+ if (value && !ks_safe_strcasecmp(value, target)) {
+ ks_hash_remove(brmgr->identities, (void *)key);
+
+ ks_log(KS_LOG_DEBUG, "Identity Removed: %s through %s\n", key, value);
+ }
+
+ ks_hash_write_unlock(brmgr->identities);
+
+ //if (blade_routemgr_master_local(blade_handle_routemgr_get(brmgr->handle))) {
+ // cJSON *params = cJSON_CreateObject();
+ // cJSON_AddStringToObject(params, "nodeid", target);
+ // blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(brmgr->handle), BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, "blade.presence", "leave", "left", params, NULL, NULL);
+ // cJSON_Delete(params);
+ //}
+
+ return KS_STATUS_SUCCESS;
+}
+
/* For Emacs:
* Local Variables:
* mode:c
diff --git a/libs/libblade/src/blade_rpc.c b/libs/libblade/src/blade_rpc.c
index 51a5251645..9e92fbc016 100644
--- a/libs/libblade/src/blade_rpc.c
+++ b/libs/libblade/src/blade_rpc.c
@@ -38,7 +38,6 @@ struct blade_rpc_s {
const char *method;
const char *protocol;
- const char *realm;
blade_rpc_request_callback_t callback;
void *data;
@@ -84,7 +83,7 @@ static void blade_rpc_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t act
}
}
-KS_DECLARE(ks_status_t) blade_rpc_create(blade_rpc_t **brpcP, blade_handle_t *bh, const char *method, const char *protocol, const char *realm, blade_rpc_request_callback_t callback, void *data)
+KS_DECLARE(ks_status_t) blade_rpc_create(blade_rpc_t **brpcP, blade_handle_t *bh, const char *method, const char *protocol, blade_rpc_request_callback_t callback, void *data)
{
blade_rpc_t *brpc = NULL;
ks_pool_t *pool = NULL;
@@ -101,7 +100,6 @@ KS_DECLARE(ks_status_t) blade_rpc_create(blade_rpc_t **brpcP, blade_handle_t *bh
brpc->handle = bh;
brpc->method = ks_pstrdup(pool, method);
if (protocol) brpc->protocol = ks_pstrdup(pool, protocol);
- if (realm) brpc->realm = ks_pstrdup(pool, realm);
brpc->callback = callback;
brpc->data = data;
@@ -151,13 +149,6 @@ KS_DECLARE(const char *) blade_rpc_protocol_get(blade_rpc_t *brpc)
return brpc->protocol;
}
-KS_DECLARE(const char *) blade_rpc_realm_get(blade_rpc_t *brpc)
-{
- ks_assert(brpc);
-
- return brpc->realm;
-}
-
KS_DECLARE(blade_rpc_request_callback_t) blade_rpc_callback_get(blade_rpc_t *brpc)
{
ks_assert(brpc);
diff --git a/libs/libblade/src/blade_rpcmgr.c b/libs/libblade/src/blade_rpcmgr.c
index 101128ddba..a8014388be 100644
--- a/libs/libblade/src/blade_rpcmgr.c
+++ b/libs/libblade/src/blade_rpcmgr.c
@@ -177,7 +177,7 @@ KS_DECLARE(ks_status_t) blade_rpcmgr_corerpc_remove(blade_rpcmgr_t *brpcmgr, bla
return KS_STATUS_SUCCESS;
}
-KS_DECLARE(blade_rpc_t *) blade_rpcmgr_protocolrpc_lookup(blade_rpcmgr_t *brpcmgr, const char *method, const char *protocol, const char *realm)
+KS_DECLARE(blade_rpc_t *) blade_rpcmgr_protocolrpc_lookup(blade_rpcmgr_t *brpcmgr, const char *method, const char *protocol)
{
blade_rpc_t *brpc = NULL;
char *key = NULL;
@@ -185,9 +185,8 @@ KS_DECLARE(blade_rpc_t *) blade_rpcmgr_protocolrpc_lookup(blade_rpcmgr_t *brpcmg
ks_assert(brpcmgr);
ks_assert(method);
ks_assert(protocol);
- ks_assert(realm);
- key = ks_psprintf(ks_pool_get(brpcmgr), "%s@%s/%s", protocol, realm, method);
+ key = ks_psprintf(ks_pool_get(brpcmgr), "%s:%s", protocol, method);
brpc = ks_hash_search(brpcmgr->protocolrpcs, (void *)key, KS_READLOCKED);
// @todo if (brpc) blade_rpc_read_lock(brpc);
ks_hash_read_unlock(brpcmgr->protocolrpcs);
@@ -201,7 +200,6 @@ KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_add(blade_rpcmgr_t *brpcmgr, bl
{
const char *method = NULL;
const char *protocol = NULL;
- const char *realm = NULL;
char *key = NULL;
ks_assert(brpcmgr);
@@ -213,10 +211,7 @@ KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_add(blade_rpcmgr_t *brpcmgr, bl
protocol = blade_rpc_protocol_get(brpc);
ks_assert(protocol);
- realm = blade_rpc_realm_get(brpc);
- ks_assert(realm);
-
- key = ks_psprintf(ks_pool_get(brpcmgr), "%s@%s/%s", protocol, realm, method);
+ key = ks_psprintf(ks_pool_get(brpcmgr), "%s:%s", protocol, method);
ks_assert(key);
ks_hash_insert(brpcmgr->protocolrpcs, (void *)key, (void *)brpc);
@@ -231,7 +226,6 @@ KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_remove(blade_rpcmgr_t *brpcmgr,
{
const char *method = NULL;
const char *protocol = NULL;
- const char *realm = NULL;
char *key = NULL;
ks_assert(brpcmgr);
@@ -243,10 +237,7 @@ KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_remove(blade_rpcmgr_t *brpcmgr,
protocol = blade_rpc_protocol_get(brpc);
ks_assert(protocol);
- realm = blade_rpc_realm_get(brpc);
- ks_assert(realm);
-
- key = ks_psprintf(ks_pool_get(brpcmgr), "%s@%s/%s", protocol, realm, method);
+ key = ks_psprintf(ks_pool_get(brpcmgr), "%s:%s", protocol, method);
ks_assert(key);
ks_hash_remove(brpcmgr->protocolrpcs, (void *)key);
diff --git a/libs/libblade/src/blade_session.c b/libs/libblade/src/blade_session.c
index 462c4713a4..99626209e2 100644
--- a/libs/libblade/src/blade_session.c
+++ b/libs/libblade/src/blade_session.c
@@ -189,7 +189,7 @@ KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs)
}
ks_hash_read_unlock(bs->routes);
- // this will also clear the local id, master id and realms in the handle if this is the upstream session
+ // this will also clear the local id, and master id in the handle if this is the upstream session
blade_sessionmgr_session_remove(blade_handle_sessionmgr_get(bs->handle), bs);
while (ks_q_trypop(bs->sending, (void **)&json) == KS_STATUS_SUCCESS && json) cJSON_Delete(json);
@@ -641,15 +641,16 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
if (params) {
const char *params_requester_nodeid = cJSON_GetObjectCstr(params, "requester-nodeid");
const char *params_responder_nodeid = cJSON_GetObjectCstr(params, "responder-nodeid");
- if (params_requester_nodeid && params_responder_nodeid && !blade_upstreammgr_localid_compare(blade_handle_upstreammgr_get(bh), params_responder_nodeid)) {
+ if (params_requester_nodeid && params_responder_nodeid && !blade_routemgr_local_check(blade_handle_routemgr_get(bh), params_responder_nodeid)) {
// not meant for local processing, continue with standard unicast routing for requests
blade_session_t *bs_router = blade_routemgr_route_lookup(blade_handle_routemgr_get(bh), params_responder_nodeid);
if (!bs_router) {
- bs_router = blade_upstreammgr_session_get(blade_handle_upstreammgr_get(bh));
+ bs_router = blade_routemgr_upstream_lookup(blade_handle_routemgr_get(bh));
if (!bs_router) {
cJSON *res = NULL;
cJSON *res_error = NULL;
+ // @todo adjust error when this is master to be route unavailable
ks_log(KS_LOG_DEBUG, "Session (%s) request (%s => %s) but upstream session unavailable\n", blade_session_id_get(bs), params_requester_nodeid, params_responder_nodeid);
blade_rpc_error_raw_create(&res, &res_error, id, -32603, "Upstream session unavailable");
@@ -714,11 +715,11 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
if (object) {
const char *object_requester_nodeid = cJSON_GetObjectCstr(object, "requester-nodeid");
const char *object_responder_nodeid = cJSON_GetObjectCstr(object, "responder-nodeid");
- if (object_requester_nodeid && object_responder_nodeid && !blade_upstreammgr_localid_compare(blade_handle_upstreammgr_get(bh), object_requester_nodeid)) {
+ if (object_requester_nodeid && object_responder_nodeid && !blade_routemgr_local_check(blade_handle_routemgr_get(bh), object_requester_nodeid)) {
// not meant for local processing, continue with standard unicast routing for responses
blade_session_t *bs_router = blade_routemgr_route_lookup(blade_handle_routemgr_get(bh), object_requester_nodeid);
if (!bs_router) {
- bs_router = blade_upstreammgr_session_get(blade_handle_upstreammgr_get(bh));
+ bs_router = blade_routemgr_upstream_lookup(blade_handle_routemgr_get(bh));
if (!bs_router) {
ks_log(KS_LOG_DEBUG, "Session (%s) response (%s <= %s) but upstream session unavailable\n", blade_session_id_get(bs), object_requester_nodeid, object_responder_nodeid);
return KS_STATUS_DISCONNECTED;
diff --git a/libs/libblade/src/blade_sessionmgr.c b/libs/libblade/src/blade_sessionmgr.c
index 5e13bc69a2..593317c37d 100644
--- a/libs/libblade/src/blade_sessionmgr.c
+++ b/libs/libblade/src/blade_sessionmgr.c
@@ -183,6 +183,7 @@ KS_DECLARE(ks_status_t) blade_sessionmgr_session_add(blade_sessionmgr_t *bsmgr,
KS_DECLARE(ks_status_t) blade_sessionmgr_session_remove(blade_sessionmgr_t *bsmgr, blade_session_t *bs)
{
const char *id = NULL;
+ blade_routemgr_t *routemgr = NULL;
ks_assert(bsmgr);
ks_assert(bs);
@@ -194,9 +195,17 @@ KS_DECLARE(ks_status_t) blade_sessionmgr_session_remove(blade_sessionmgr_t *bsmg
ks_log(KS_LOG_DEBUG, "Session Removed: %s\n", id);
- if (blade_upstreammgr_localid_compare(blade_handle_upstreammgr_get(bsmgr->handle), id)) {
- blade_upstreammgr_localid_set(blade_handle_upstreammgr_get(bsmgr->handle), NULL);
- blade_upstreammgr_masterid_set(blade_handle_upstreammgr_get(bsmgr->handle), NULL);
+ routemgr = blade_handle_routemgr_get(bsmgr->handle);
+ if (blade_routemgr_local_check(routemgr, id)) {
+ blade_routemgr_local_set(routemgr, NULL);
+ blade_routemgr_master_set(routemgr, NULL);
+
+ // @todo this is the upstream session that has actually terminated, any downstream connections should also be terminated
+ // properly, such that the downstream clients will not attempt to reconnect with the same session id, but will instead
+ // reestablish new sessions and likewise terminate downstream sessions
+ // @todo this also reflects that downstream connections should not be accepted in the transport implementation until an
+ // upstream connection has been established, unless it is the master node which has no upstream session, plumbing to
+ // support this does not yet exist
}
blade_session_write_unlock(bs);
diff --git a/libs/libblade/src/blade_stack.c b/libs/libblade/src/blade_stack.c
index 929c6cb592..a3bfecbf40 100644
--- a/libs/libblade/src/blade_stack.c
+++ b/libs/libblade/src/blade_stack.c
@@ -40,13 +40,14 @@ struct blade_handle_s {
blade_rpcmgr_t *rpcmgr;
blade_routemgr_t *routemgr;
blade_subscriptionmgr_t *subscriptionmgr;
- blade_upstreammgr_t *upstreammgr;
blade_mastermgr_t *mastermgr;
blade_connectionmgr_t *connectionmgr;
blade_sessionmgr_t *sessionmgr;
};
+ks_bool_t blade_rpcroute_request_handler(blade_rpc_request_t *brpcreq, void *data);
ks_bool_t blade_rpcregister_request_handler(blade_rpc_request_t *brpcreq, void *data);
+ks_bool_t blade_rpcregister_response_handler(blade_rpc_response_t *brpcres, void *data);
ks_bool_t blade_rpcpublish_request_handler(blade_rpc_request_t *brpcreq, void *data);
ks_bool_t blade_rpcauthorize_request_handler(blade_rpc_request_t *brpcreq, void *data);
ks_bool_t blade_rpclocate_request_handler(blade_rpc_request_t *brpcreq, void *data);
@@ -70,7 +71,6 @@ static void blade_handle_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t
blade_rpcmgr_destroy(&bh->rpcmgr);
blade_routemgr_destroy(&bh->routemgr);
blade_subscriptionmgr_destroy(&bh->subscriptionmgr);
- blade_upstreammgr_destroy(&bh->upstreammgr);
blade_mastermgr_destroy(&bh->mastermgr);
blade_connectionmgr_destroy(&bh->connectionmgr);
blade_sessionmgr_destroy(&bh->sessionmgr);
@@ -111,9 +111,6 @@ KS_DECLARE(ks_status_t) blade_handle_create(blade_handle_t **bhP)
blade_subscriptionmgr_create(&bh->subscriptionmgr, bh);
ks_assert(bh->subscriptionmgr);
- blade_upstreammgr_create(&bh->upstreammgr, bh);
- ks_assert(bh->upstreammgr);
-
blade_mastermgr_create(&bh->mastermgr, bh);
ks_assert(bh->mastermgr);
@@ -180,33 +177,36 @@ KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_
return KS_STATUS_FAIL;
}
- // register internal transport for secure websockets
+ // internal transport for secure websockets
blade_transport_wss_create(&bt, bh);
ks_assert(bt);
blade_transportmgr_default_set(bh->transportmgr, bt);
blade_transportmgr_transport_add(bh->transportmgr, bt);
- // register internal core rpcs for blade.xxx
- blade_rpc_create(&brpc, bh, "blade.register", NULL, NULL, blade_rpcregister_request_handler, NULL);
+ // internal core rpcs for blade.xxx
+ blade_rpc_create(&brpc, bh, "blade.route", NULL, blade_rpcroute_request_handler, NULL);
blade_rpcmgr_corerpc_add(bh->rpcmgr, brpc);
- blade_rpc_create(&brpc, bh, "blade.publish", NULL, NULL, blade_rpcpublish_request_handler, NULL);
+ blade_rpc_create(&brpc, bh, "blade.register", NULL, blade_rpcregister_request_handler, NULL);
blade_rpcmgr_corerpc_add(bh->rpcmgr, brpc);
- blade_rpc_create(&brpc, bh, "blade.authorize", NULL, NULL, blade_rpcauthorize_request_handler, NULL);
+ blade_rpc_create(&brpc, bh, "blade.publish", NULL, blade_rpcpublish_request_handler, NULL);
blade_rpcmgr_corerpc_add(bh->rpcmgr, brpc);
- blade_rpc_create(&brpc, bh, "blade.locate", NULL, NULL, blade_rpclocate_request_handler, NULL);
+ blade_rpc_create(&brpc, bh, "blade.authorize", NULL, blade_rpcauthorize_request_handler, NULL);
blade_rpcmgr_corerpc_add(bh->rpcmgr, brpc);
- blade_rpc_create(&brpc, bh, "blade.execute", NULL, NULL, blade_rpcexecute_request_handler, NULL);
+ blade_rpc_create(&brpc, bh, "blade.locate", NULL, blade_rpclocate_request_handler, NULL);
blade_rpcmgr_corerpc_add(bh->rpcmgr, brpc);
- blade_rpc_create(&brpc, bh, "blade.subscribe", NULL, NULL, blade_rpcsubscribe_request_handler, NULL);
+ blade_rpc_create(&brpc, bh, "blade.execute", NULL, blade_rpcexecute_request_handler, NULL);
blade_rpcmgr_corerpc_add(bh->rpcmgr, brpc);
- blade_rpc_create(&brpc, bh, "blade.broadcast", NULL, NULL, blade_rpcbroadcast_request_handler, NULL);
+ blade_rpc_create(&brpc, bh, "blade.subscribe", NULL, blade_rpcsubscribe_request_handler, NULL);
+ blade_rpcmgr_corerpc_add(bh->rpcmgr, brpc);
+
+ blade_rpc_create(&brpc, bh, "blade.broadcast", NULL, blade_rpcbroadcast_request_handler, NULL);
blade_rpcmgr_corerpc_add(bh->rpcmgr, brpc);
@@ -262,12 +262,6 @@ KS_DECLARE(blade_subscriptionmgr_t *) blade_handle_subscriptionmgr_get(blade_han
return bh->subscriptionmgr;
}
-KS_DECLARE(blade_upstreammgr_t *) blade_handle_upstreammgr_get(blade_handle_t *bh)
-{
- ks_assert(bh);
- return bh->upstreammgr;
-}
-
KS_DECLARE(blade_mastermgr_t *) blade_handle_mastermgr_get(blade_handle_t *bh)
{
ks_assert(bh);
@@ -290,16 +284,20 @@ KS_DECLARE(blade_sessionmgr_t *) blade_handle_sessionmgr_get(blade_handle_t *bh)
KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connection_t **bcP, blade_identity_t *target, const char *session_id)
{
ks_status_t ret = KS_STATUS_SUCCESS;
+ blade_session_t *bs = NULL;
blade_transport_t *bt = NULL;
blade_transport_callbacks_t *callbacks = NULL;
ks_assert(bh);
ks_assert(target);
- // @todo mini state machine to deal with upstream establishment to avoid attempting multiple upstream connects at the same time
- if (blade_upstreammgr_session_established(bh->upstreammgr)) return KS_STATUS_DUPLICATE_OPERATION;
+ // @todo mini state machine to deal with upstream establishment to avoid attempting multiple upstream connects at the same time?
+ if ((bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
+ blade_session_read_unlock(bs);
+ return KS_STATUS_DUPLICATE_OPERATION;
+ }
- bt = blade_transportmgr_transport_lookup(bh->transportmgr, blade_identity_parameter_get(target, "transport"), KS_TRUE);
+ bt = blade_transportmgr_transport_lookup(bh->transportmgr, blade_identity_parameter_lookup(target, "transport"), KS_TRUE);
ks_assert(bt);
callbacks = blade_transport_callbacks_get(bt);
@@ -313,23 +311,32 @@ KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connectio
// BLADE PROTOCOL HANDLERS
-// @todo revisit all error sending. JSONRPC "error" should only be used for json parsing errors, change the rest to internal errors for each of the corerpcs
+// @todo revisit all error sending. JSONRPC "error" should only be used for missing and invalid parameter errors, change the rest to internal errors for each of the corerpcs
// @todo all higher level errors should be handled by each of the calls internally so that a normal result response can be sent with an error block inside the result
// which is important for implementation of blade.execute where errors can be relayed back to the requester properly
+typedef struct blade_rpcregister_data_s blade_rpcregister_data_t;
+struct blade_rpcregister_data_s {
+ blade_rpc_response_callback_t original_callback;
+ void *original_data;
+ const char *original_requestid;
+};
+
typedef struct blade_rpcsubscribe_data_s blade_rpcsubscribe_data_t;
struct blade_rpcsubscribe_data_s {
blade_rpc_response_callback_t original_callback;
void *original_data;
+ const char *original_requestid;
blade_rpc_request_callback_t channel_callback;
void *channel_data;
- const char *relayed_messageid;
};
-ks_status_t blade_handle_rpcsubscribe_raw(blade_handle_t *bh, blade_rpcsubscribe_command_t command, const char *protocol, const char *realm, cJSON *channels, const char *subscriber, ks_bool_t downstream, blade_rpc_response_callback_t callback, blade_rpcsubscribe_data_t *data);
+ks_status_t blade_handle_rpcregister_raw(blade_handle_t *bh, const char *identity, const char *nodeid, blade_rpc_response_callback_t callback, blade_rpcregister_data_t *data);
+ks_status_t blade_handle_rpcsubscribe_raw(blade_handle_t *bh, blade_rpcsubscribe_command_t command, const char *protocol, cJSON *channels, const char *subscriber, ks_bool_t downstream, blade_rpc_response_callback_t callback, blade_rpcsubscribe_data_t *data);
-// blade.register request generator
-KS_DECLARE(ks_status_t) blade_handle_rpcregister(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, blade_rpc_response_callback_t callback, void *data)
+
+// blade.route request generator
+KS_DECLARE(ks_status_t) blade_handle_rpcroute(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, blade_rpc_response_callback_t callback, void *data)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_session_t *bs = NULL;
@@ -340,7 +347,8 @@ KS_DECLARE(ks_status_t) blade_handle_rpcregister(blade_handle_t *bh, const char
ks_assert(bh);
ks_assert(nodeid);
- if (!(bs = blade_upstreammgr_session_get(bh->upstreammgr))) {
+
+ if (!(bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
ret = KS_STATUS_DISCONNECTED;
goto done;
}
@@ -348,13 +356,13 @@ KS_DECLARE(ks_status_t) blade_handle_rpcregister(blade_handle_t *bh, const char
pool = ks_pool_get(bh);
ks_assert(pool);
- blade_rpc_request_raw_create(pool, &req, &req_params, NULL, "blade.register");
+ blade_rpc_request_raw_create(pool, &req, &req_params, NULL, "blade.route");
// fill in the req_params
cJSON_AddStringToObject(req_params, "nodeid", nodeid);
if (remove) cJSON_AddTrueToObject(req_params, "remove");
- ks_log(KS_LOG_DEBUG, "Session (%s) register request (%s %s) started\n", blade_session_id_get(bs), remove ? "removing" : "adding", nodeid);
+ ks_log(KS_LOG_DEBUG, "Session (%s) route request (%s %s) started\n", blade_session_id_get(bs), remove ? "removing" : "adding", nodeid);
ret = blade_session_send(bs, req, callback, data);
@@ -365,8 +373,8 @@ done:
return ret;
}
-// blade.register request handler
-ks_bool_t blade_rpcregister_request_handler(blade_rpc_request_t *brpcreq, void *data)
+// blade.route request handler
+ks_bool_t blade_rpcroute_request_handler(blade_rpc_request_t *brpcreq, void *data)
{
blade_handle_t *bh = NULL;
blade_session_t *bs = NULL;
@@ -391,7 +399,7 @@ ks_bool_t blade_rpcregister_request_handler(blade_rpc_request_t *brpcreq, void *
req_params = cJSON_GetObjectItem(req, "params");
if (!req_params) {
- ks_log(KS_LOG_DEBUG, "Session (%s) register request missing 'params' object\n", blade_session_id_get(bs));
+ ks_log(KS_LOG_DEBUG, "Session (%s) route request missing 'params' object\n", blade_session_id_get(bs));
blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params object");
blade_session_send(bs, res, NULL, NULL);
goto done;
@@ -399,7 +407,7 @@ ks_bool_t blade_rpcregister_request_handler(blade_rpc_request_t *brpcreq, void *
req_params_nodeid = cJSON_GetObjectCstr(req_params, "nodeid");
if (!req_params_nodeid) {
- ks_log(KS_LOG_DEBUG, "Session (%s) register request missing 'nodeid'\n", blade_session_id_get(bs));
+ ks_log(KS_LOG_DEBUG, "Session (%s) route request missing 'nodeid'\n", blade_session_id_get(bs));
blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params nodeid");
blade_session_send(bs, res, NULL, NULL);
goto done;
@@ -407,7 +415,7 @@ ks_bool_t blade_rpcregister_request_handler(blade_rpc_request_t *brpcreq, void *
req_params_remove = cJSON_GetObjectItem(req_params, "remove");
remove = req_params_remove && req_params_remove->type == cJSON_True;
- ks_log(KS_LOG_DEBUG, "Session (%s) register request (%s %s) processing\n", blade_session_id_get(bs), remove ? "removing" : "adding", req_params_nodeid);
+ ks_log(KS_LOG_DEBUG, "Session (%s) route request (%s %s) processing\n", blade_session_id_get(bs), remove ? "removing" : "adding", req_params_nodeid);
if (remove) {
blade_session_route_remove(bs, req_params_nodeid);
@@ -429,22 +437,70 @@ done:
}
-// blade.publish request generator
-KS_DECLARE(ks_status_t) blade_handle_rpcpublish(blade_handle_t *bh, blade_rpcpublish_command_t command, const char *protocol, const char *realm, cJSON *channels, blade_rpc_response_callback_t callback, void *data)
+static void blade_rpcregister_data_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+ blade_rpcregister_data_t *brpcrd = (blade_rpcregister_data_t *)ptr;
+
+ ks_assert(brpcrd);
+
+ switch (action) {
+ case KS_MPCL_ANNOUNCE:
+ break;
+ case KS_MPCL_TEARDOWN:
+ if (brpcrd->original_requestid) ks_pool_free(&brpcrd->original_requestid);
+ break;
+ case KS_MPCL_DESTROY:
+ break;
+ }
+}
+
+// blade.register request generator
+KS_DECLARE(ks_status_t) blade_handle_rpcregister(blade_handle_t *bh, const char *identity, blade_rpc_response_callback_t callback, void *data)
+{
+ ks_status_t ret = KS_STATUS_SUCCESS;
+ blade_session_t *bs = NULL;
+ const char *localid = NULL;
+ blade_rpcregister_data_t *temp_data = NULL;
+
+ ks_assert(bh);
+ ks_assert(identity);
+
+ if (!(bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
+ ret = KS_STATUS_DISCONNECTED;
+ goto done;
+ }
+
+ temp_data = (blade_rpcregister_data_t *)ks_pool_alloc(ks_pool_get(bh), sizeof(blade_rpcregister_data_t));
+ temp_data->original_callback = callback;
+ temp_data->original_data = data;
+ ks_pool_set_cleanup(temp_data, NULL, blade_rpcregister_data_cleanup);
+
+ blade_routemgr_local_copy(bh->routemgr, &localid);
+
+ ret = blade_handle_rpcregister_raw(bh, identity, localid, blade_rpcregister_response_handler, temp_data);
+
+ ks_pool_free(&localid);
+
+ ks_log(KS_LOG_DEBUG, "Session (%s) register request (%s) started\n", blade_session_id_get(bs), identity);
+
+done:
+ if (bs) blade_session_read_unlock(bs);
+
+ return ret;
+}
+
+ks_status_t blade_handle_rpcregister_raw(blade_handle_t *bh, const char *identity, const char *nodeid, blade_rpc_response_callback_t callback, blade_rpcregister_data_t *data)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_session_t *bs = NULL;
ks_pool_t *pool = NULL;
cJSON *req = NULL;
cJSON *req_params = NULL;
- const char *id = NULL;
ks_assert(bh);
- ks_assert(protocol);
- ks_assert(realm);
+ ks_assert(identity);
- // @todo consideration for the Master trying to publish a protocol, with no upstream
- if (!(bs = blade_upstreammgr_session_get(bh->upstreammgr))) {
+ if (!(bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
ret = KS_STATUS_DISCONNECTED;
goto done;
}
@@ -452,6 +508,209 @@ KS_DECLARE(ks_status_t) blade_handle_rpcpublish(blade_handle_t *bh, blade_rpcpub
pool = ks_pool_get(bh);
ks_assert(pool);
+ blade_rpc_request_raw_create(pool, &req, &req_params, NULL, "blade.register");
+
+ // fill in the req_params
+ cJSON_AddStringToObject(req_params, "identity", identity);
+ cJSON_AddStringToObject(req_params, "nodeid", nodeid);
+
+ ret = blade_session_send(bs, req, callback, data);
+
+done:
+ if (req) cJSON_Delete(req);
+ if (bs) blade_session_read_unlock(bs);
+
+ return ret;
+}
+
+// blade.register request handler
+ks_bool_t blade_rpcregister_request_handler(blade_rpc_request_t *brpcreq, void *data)
+{
+ blade_handle_t *bh = NULL;
+ blade_session_t *bs = NULL;
+ ks_pool_t *pool = NULL;
+ cJSON *req = NULL;
+ cJSON *req_params = NULL;
+ const char *req_params_identity = NULL;
+ const char *req_params_nodeid = NULL;
+ cJSON *res = NULL;
+ cJSON *res_result = NULL;
+ blade_identity_t *identity = NULL;
+
+ ks_assert(brpcreq);
+
+ bh = blade_rpc_request_handle_get(brpcreq);
+ ks_assert(bh);
+
+ pool = ks_pool_get(bh);
+ ks_assert(pool);
+
+ bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bh), blade_rpc_request_sessionid_get(brpcreq));
+ ks_assert(bs);
+
+ req = blade_rpc_request_message_get(brpcreq);
+ ks_assert(req);
+
+ req_params = cJSON_GetObjectItem(req, "params");
+ if (!req_params) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) register request missing 'params' object\n", blade_session_id_get(bs));
+ blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params object");
+ blade_session_send(bs, res, NULL, NULL);
+ goto done;
+ }
+
+ req_params_identity = cJSON_GetObjectCstr(req_params, "identity");
+ if (!req_params_identity) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) register request missing 'identity'\n", blade_session_id_get(bs));
+ blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params identity");
+ blade_session_send(bs, res, NULL, NULL);
+ goto done;
+ }
+
+ blade_identity_create(&identity, pool);
+ if (blade_identity_parse(identity, req_params_identity) != KS_STATUS_SUCCESS) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) register request invalid 'identity'\n", blade_session_id_get(bs));
+ blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Invalid params identity");
+ blade_session_send(bs, res, NULL, NULL);
+ goto done;
+ }
+
+ req_params_nodeid = cJSON_GetObjectCstr(req_params, "nodeid");
+ if (!req_params_nodeid) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) register request missing 'nodeid'\n", blade_session_id_get(bs));
+ blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params nodeid");
+ blade_session_send(bs, res, NULL, NULL);
+ goto done;
+ }
+
+ ks_log(KS_LOG_DEBUG, "Session (%s) register request (%s for %s) processing\n", blade_session_id_get(bs), req_params_identity, req_params_nodeid);
+
+ if (blade_routemgr_master_local(blade_handle_routemgr_get(bh))) {
+ // @todo add identity mapping to nodeid, normally handled in the response handler
+ blade_routemgr_identity_add(bh->routemgr, identity, req_params_nodeid);
+
+ // @todo this is the masters chance to do any additional validation on the identity registration, just trust it for now
+ blade_rpc_response_raw_create(&res, &res_result, blade_rpc_request_messageid_get(brpcreq));
+
+ cJSON_AddStringToObject(res_result, "identity", req_params_identity);
+ cJSON_AddStringToObject(res_result, "nodeid", req_params_nodeid);
+
+ // request was just received on a session that is already read locked, so we can assume the response goes back on the same session without further lookup
+ blade_session_send(bs, res, NULL, NULL);
+ } else {
+ blade_rpcregister_data_t *temp_data = (blade_rpcregister_data_t *)ks_pool_alloc(pool, sizeof(blade_rpcregister_data_t));
+ temp_data->original_requestid = ks_pstrdup(pool, blade_rpc_request_messageid_get(brpcreq));
+ ks_pool_set_cleanup(temp_data, NULL, blade_rpcregister_data_cleanup);
+
+ blade_handle_rpcregister_raw(bh, req_params_identity, req_params_nodeid, blade_rpcregister_response_handler, temp_data);
+ }
+
+done:
+ if (identity) blade_identity_destroy(&identity);
+ if (res) cJSON_Delete(res);
+ if (bs) blade_session_read_unlock(bs);
+
+ return KS_FALSE;
+}
+
+// blade.register response handler
+ks_bool_t blade_rpcregister_response_handler(blade_rpc_response_t *brpcres, void *data)
+{
+ ks_bool_t ret = KS_FALSE;
+ blade_handle_t *bh = NULL;
+ blade_session_t *bs = NULL;
+ blade_rpcregister_data_t *temp_data = NULL;
+ cJSON *res = NULL;
+ cJSON *res_result = NULL;
+ const char *res_result_identity = NULL;
+ const char *res_result_nodeid = NULL;
+ blade_identity_t *identity = NULL;
+
+ ks_assert(brpcres);
+
+ bh = blade_rpc_response_handle_get(brpcres);
+ ks_assert(bh);
+
+ bs = blade_sessionmgr_session_lookup(bh->sessionmgr, blade_rpc_response_sessionid_get(brpcres));
+ ks_assert(bs);
+
+ temp_data = (blade_rpcregister_data_t *)data;
+
+ res = blade_rpc_response_message_get(brpcres);
+ ks_assert(res);
+
+ res_result = cJSON_GetObjectItem(res, "result");
+ if (!res_result) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) register response missing 'result' object\n", blade_session_id_get(bs));
+ goto done;
+ }
+
+ res_result_identity = cJSON_GetObjectCstr(res_result, "identity");
+ if (!res_result_identity) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) register response missing 'identity'\n", blade_session_id_get(bs));
+ goto done;
+ }
+
+ blade_identity_create(&identity, ks_pool_get(bh));
+
+ if (blade_identity_parse(identity, res_result_identity) != KS_STATUS_SUCCESS) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) register response invalid 'identity'\n", blade_session_id_get(bs));
+ goto done;
+ }
+
+ res_result_nodeid = cJSON_GetObjectCstr(res_result, "nodeid");
+ if (!res_result_nodeid) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) register response missing 'nodeid'\n", blade_session_id_get(bs));
+ goto done;
+ }
+
+ blade_routemgr_identity_add(bh->routemgr, identity, res_result_nodeid);
+
+ // @note this should only happen on the last response, received by the registering node
+ if (temp_data && temp_data->original_callback) ret = temp_data->original_callback(brpcres, temp_data->original_data);
+
+ if (temp_data && temp_data->original_requestid) {
+ blade_session_t *relay = NULL;
+ if (!(relay = blade_routemgr_route_lookup(bh->routemgr, res_result_nodeid))) {
+ goto done;
+ }
+
+ blade_rpc_response_raw_create(&res, &res_result, temp_data->original_requestid);
+
+ cJSON_AddStringToObject(res_result, "identity", res_result_identity);
+ cJSON_AddStringToObject(res_result, "nodeid", res_result_nodeid);
+
+ blade_session_send(relay, res, NULL, NULL);
+
+ cJSON_Delete(res);
+
+ blade_session_read_unlock(relay);
+ }
+
+done:
+ if (temp_data) ks_pool_free(&temp_data);
+ if (identity) blade_identity_destroy(&identity);
+ blade_session_read_unlock(bs);
+ return ret;
+}
+
+// blade.publish request generator
+KS_DECLARE(ks_status_t) blade_handle_rpcpublish(blade_handle_t *bh, blade_rpcpublish_command_t command, const char *protocol, cJSON *channels, blade_rpc_response_callback_t callback, void *data)
+{
+ ks_status_t ret = KS_STATUS_SUCCESS;
+ blade_session_t *bs = NULL;
+ cJSON *req = NULL;
+ cJSON *req_params = NULL;
+
+ ks_assert(bh);
+ ks_assert(protocol);
+
+ // @todo consideration for the Master trying to publish a protocol, with no upstream
+ if (!(bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
+ ret = KS_STATUS_DISCONNECTED;
+ goto done;
+ }
+
// @todo validate command and parameters
switch (command) {
case BLADE_RPCPUBLISH_COMMAND_CONTROLLER_ADD:
@@ -472,23 +731,17 @@ KS_DECLARE(ks_status_t) blade_handle_rpcpublish(blade_handle_t *bh, blade_rpcpub
}
// create the response
- blade_rpc_request_raw_create(pool, &req, &req_params, NULL, "blade.publish");
+ blade_rpc_request_raw_create(ks_pool_get(bh), &req, &req_params, NULL, "blade.publish");
cJSON_AddNumberToObject(req_params, "command", command);
cJSON_AddStringToObject(req_params, "protocol", protocol);
- cJSON_AddStringToObject(req_params, "realm", realm);
- blade_upstreammgr_localid_copy(bh->upstreammgr, pool, &id);
- ks_assert(id);
+ blade_routemgr_local_pack(bh->routemgr, req_params, "requester-nodeid");
- cJSON_AddStringToObject(req_params, "requester-nodeid", id);
- ks_pool_free(&id);
-
- blade_upstreammgr_masterid_copy(bh->upstreammgr, pool, &id);
- ks_assert(id);
-
- cJSON_AddStringToObject(req_params, "responder-nodeid", id);
- ks_pool_free(&id);
+ if (!blade_routemgr_master_pack(bh->routemgr, req_params, "responder-nodeid")) {
+ ret = KS_STATUS_DISCONNECTED;
+ goto done;
+ }
if (channels) cJSON_AddItemToObject(req_params, "channels", cJSON_Duplicate(channels, 1));
@@ -513,12 +766,14 @@ ks_bool_t blade_rpcpublish_request_handler(blade_rpc_request_t *brpcreq, void *d
cJSON *req = NULL;
cJSON *req_params = NULL;
cJSON *req_params_channels = NULL;
+ cJSON *req_params_channels_element = NULL;
+ cJSON *req_params_channels_element_flags = NULL;
cJSON *req_params_command = NULL;
blade_rpcpublish_command_t command = BLADE_RPCPUBLISH_COMMAND_NONE;
const char *req_params_protocol = NULL;
- const char *req_params_realm = NULL;
const char *req_params_requester_nodeid = NULL;
const char *req_params_responder_nodeid = NULL;
+ const char *req_params_channels_element_name = NULL;
cJSON *res = NULL;
cJSON *res_result = NULL;
@@ -565,16 +820,6 @@ ks_bool_t blade_rpcpublish_request_handler(blade_rpc_request_t *brpcreq, void *d
goto done;
}
- req_params_realm = cJSON_GetObjectCstr(req_params, "realm");
- if (!req_params_realm) {
- ks_log(KS_LOG_DEBUG, "Session (%s) publish request missing 'realm'\n", blade_session_id_get(bs));
- blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params realm");
- blade_session_send(bs, res, NULL, NULL);
- goto done;
- }
-
- // @todo confirm the realm is permitted for the session, this gets complicated with subdomains, skipping for now
-
req_params_requester_nodeid = cJSON_GetObjectCstr(req_params, "requester-nodeid");
if (!req_params_requester_nodeid) {
ks_log(KS_LOG_DEBUG, "Session (%s) publish request missing 'requester-nodeid'\n", blade_session_id_get(bs));
@@ -591,7 +836,7 @@ ks_bool_t blade_rpcpublish_request_handler(blade_rpc_request_t *brpcreq, void *d
goto done;
}
- if (!blade_upstreammgr_masterid_compare(bh->upstreammgr, req_params_responder_nodeid)) {
+ if (!blade_routemgr_master_check(bh->routemgr, req_params_responder_nodeid)) {
ks_log(KS_LOG_DEBUG, "Session (%s) publish request invalid 'responder-nodeid' (%s)\n", blade_session_id_get(bs), req_params_responder_nodeid);
blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Invalid params responder-nodeid");
blade_session_send(bs, res, NULL, NULL);
@@ -603,8 +848,6 @@ ks_bool_t blade_rpcpublish_request_handler(blade_rpc_request_t *brpcreq, void *d
req_params_channels = cJSON_GetObjectItem(req_params, "channels");
if (req_params_channels) {
- cJSON *element = NULL;
-
if (req_params_channels->type != cJSON_Array) {
ks_log(KS_LOG_DEBUG, "Session (%s) publish request invalid 'channels' type, expected array\n", blade_session_id_get(bs));
blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Invalid params channels");
@@ -612,13 +855,29 @@ ks_bool_t blade_rpcpublish_request_handler(blade_rpc_request_t *brpcreq, void *d
goto done;
}
- cJSON_ArrayForEach(element, req_params_channels) {
- if (element->type != cJSON_String) {
- ks_log(KS_LOG_DEBUG, "Session (%s) publish request invalid 'channels' element type, expected string\n", blade_session_id_get(bs));
+ cJSON_ArrayForEach(req_params_channels_element, req_params_channels) {
+ if (req_params_channels_element->type != cJSON_Object) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) publish request invalid 'channels' element type, expected object\n", blade_session_id_get(bs));
blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Invalid params channels");
blade_session_send(bs, res, NULL, NULL);
goto done;
}
+
+ req_params_channels_element_name = cJSON_GetObjectCstr(req_params_channels_element, "name");
+ if (!req_params_channels_element_name) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) publish request missing 'channels' element name\n", blade_session_id_get(bs));
+ blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params channels element name");
+ blade_session_send(bs, res, NULL, NULL);
+ goto done;
+ }
+
+ req_params_channels_element_flags = cJSON_GetObjectItem(req_params_channels_element, "flags");
+ if (req_params_channels_element_flags && req_params_channels_element_flags->type != cJSON_Number) {
+ ks_log(KS_LOG_DEBUG, "Session (%s) publish request invalid 'channels' element flags type, expected number\n", blade_session_id_get(bs));
+ blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Invalid params channels element flags type");
+ blade_session_send(bs, res, NULL, NULL);
+ goto done;
+ }
}
}
@@ -627,30 +886,33 @@ ks_bool_t blade_rpcpublish_request_handler(blade_rpc_request_t *brpcreq, void *d
// @todo switch on publish command, make the following code for add_protocol
switch (command) {
case BLADE_RPCPUBLISH_COMMAND_CONTROLLER_ADD:
- blade_mastermgr_realm_protocol_controller_add(bh->mastermgr, req_params_realm, req_params_protocol, req_params_requester_nodeid);
+ blade_mastermgr_protocol_controller_add(bh->mastermgr, req_params_protocol, req_params_requester_nodeid);
if (req_params_channels) {
- cJSON *element = NULL;
- cJSON_ArrayForEach(element, req_params_channels) {
- blade_mastermgr_realm_protocol_channel_add(bh->mastermgr, req_params_realm, req_params_protocol, element->valuestring);
+ cJSON_ArrayForEach(req_params_channels_element, req_params_channels) {
+ req_params_channels_element_name = cJSON_GetObjectCstr(req_params_channels_element, "name");
+ req_params_channels_element_flags = cJSON_GetObjectItem(req_params_channels_element, "flags");
+
+ blade_mastermgr_protocol_channel_add(bh->mastermgr, req_params_protocol, req_params_channels_element_name, (blade_channel_flags_t)req_params_channels_element_flags->valueint);
}
}
break;
case BLADE_RPCPUBLISH_COMMAND_CONTROLLER_REMOVE:
- blade_mastermgr_realm_protocol_controller_remove(bh->mastermgr, req_params_realm, req_params_protocol, req_params_requester_nodeid);
+ blade_mastermgr_protocol_controller_remove(bh->mastermgr, req_params_protocol, req_params_requester_nodeid);
break;
case BLADE_RPCPUBLISH_COMMAND_CHANNEL_ADD:
if (req_params_channels) {
- cJSON *element = NULL;
- cJSON_ArrayForEach(element, req_params_channels) {
- blade_mastermgr_realm_protocol_channel_add(bh->mastermgr, req_params_realm, req_params_protocol, element->valuestring);
+ cJSON_ArrayForEach(req_params_channels_element, req_params_channels) {
+ req_params_channels_element_name = cJSON_GetObjectCstr(req_params_channels_element, "name");
+ req_params_channels_element_flags = cJSON_GetObjectItem(req_params_channels_element, "flags");
+ blade_mastermgr_protocol_channel_add(bh->mastermgr, req_params_protocol, req_params_channels_element_name, (blade_channel_flags_t)req_params_channels_element_flags->valueint);
}
}
break;
case BLADE_RPCPUBLISH_COMMAND_CHANNEL_REMOVE:
if (req_params_channels) {
- cJSON *element = NULL;
- cJSON_ArrayForEach(element, req_params_channels) {
- blade_mastermgr_realm_protocol_channel_remove(bh->mastermgr, req_params_realm, req_params_protocol, element->valuestring);
+ cJSON_ArrayForEach(req_params_channels_element, req_params_channels) {
+ req_params_channels_element_name = cJSON_GetObjectCstr(req_params_channels_element, "name");
+ blade_mastermgr_protocol_channel_remove(bh->mastermgr, req_params_protocol, req_params_channels_element_name);
}
}
break;
@@ -663,7 +925,6 @@ ks_bool_t blade_rpcpublish_request_handler(blade_rpc_request_t *brpcreq, void *d
blade_rpc_response_raw_create(&res, &res_result, blade_rpc_request_messageid_get(brpcreq));
cJSON_AddStringToObject(res_result, "protocol", req_params_protocol);
- cJSON_AddStringToObject(res_result, "realm", req_params_realm);
cJSON_AddStringToObject(res_result, "requester-nodeid", req_params_requester_nodeid);
cJSON_AddStringToObject(res_result, "responder-nodeid", req_params_responder_nodeid);
// @todo include a list of channels that failed to be added or removed if applicable?
@@ -681,49 +942,37 @@ done:
// blade.authorize request generator
-KS_DECLARE(ks_status_t) blade_handle_rpcauthorize(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, const char *protocol, const char *realm, cJSON *channels, blade_rpc_response_callback_t callback, void *data)
+KS_DECLARE(ks_status_t) blade_handle_rpcauthorize(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, const char *protocol, cJSON *channels, blade_rpc_response_callback_t callback, void *data)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_session_t *bs = NULL;
- ks_pool_t *pool = NULL;
cJSON *req = NULL;
cJSON *req_params = NULL;
- const char *id = NULL;
ks_assert(bh);
ks_assert(nodeid);
ks_assert(protocol);
- ks_assert(realm);
ks_assert(channels);
// @todo consideration for the Master trying to publish a protocol, with no upstream
- if (!(bs = blade_upstreammgr_session_get(bh->upstreammgr))) {
+ if (!(bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
ret = KS_STATUS_DISCONNECTED;
goto done;
}
- pool = ks_pool_get(bh);
- ks_assert(pool);
-
- blade_rpc_request_raw_create(pool, &req, &req_params, NULL, "blade.authorize");
+ blade_rpc_request_raw_create(ks_pool_get(bh), &req, &req_params, NULL, "blade.authorize");
// fill in the req_params
cJSON_AddStringToObject(req_params, "protocol", protocol);
- cJSON_AddStringToObject(req_params, "realm", realm);
if (remove) cJSON_AddTrueToObject(req_params, "remove");
cJSON_AddStringToObject(req_params, "authorized-nodeid", nodeid);
- blade_upstreammgr_localid_copy(bh->upstreammgr, pool, &id);
- ks_assert(id);
+ blade_routemgr_local_pack(bh->routemgr, req_params, "requester-nodeid");
- cJSON_AddStringToObject(req_params, "requester-nodeid", id);
- ks_pool_free(&id);
-
- blade_upstreammgr_masterid_copy(bh->upstreammgr, pool, &id);
- ks_assert(id);
-
- cJSON_AddStringToObject(req_params, "responder-nodeid", id);
- ks_pool_free(&id);
+ if (!blade_routemgr_master_pack(bh->routemgr, req_params, "responder-nodeid")) {
+ ret = KS_STATUS_DISCONNECTED;
+ goto done;
+ }
cJSON_AddItemToObject(req_params, "channels", cJSON_Duplicate(channels, 1));
@@ -752,7 +1001,6 @@ ks_bool_t blade_rpcauthorize_request_handler(blade_rpc_request_t *brpcreq, void
cJSON *channel = NULL;
ks_bool_t remove = KS_FALSE;
const char *req_params_protocol = NULL;
- const char *req_params_realm = NULL;
const char *req_params_authorized_nodeid = NULL;
const char *req_params_requester_nodeid = NULL;
const char *req_params_responder_nodeid = NULL;
@@ -789,14 +1037,6 @@ ks_bool_t blade_rpcauthorize_request_handler(blade_rpc_request_t *brpcreq, void
goto done;
}
- req_params_realm = cJSON_GetObjectCstr(req_params, "realm");
- if (!req_params_realm) {
- ks_log(KS_LOG_DEBUG, "Session (%s) authorize request missing 'realm'\n", blade_session_id_get(bs));
- blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params realm");
- blade_session_send(bs, res, NULL, NULL);
- goto done;
- }
-
req_params_remove = cJSON_GetObjectItem(req_params, "remove");
if (req_params_remove && req_params_remove->type == cJSON_True) remove = KS_TRUE;
@@ -808,8 +1048,6 @@ ks_bool_t blade_rpcauthorize_request_handler(blade_rpc_request_t *brpcreq, void
goto done;
}
- // @todo confirm the realm is permitted for the session, this gets complicated with subdomains, skipping for now
-
req_params_requester_nodeid = cJSON_GetObjectCstr(req_params, "requester-nodeid");
if (!req_params_requester_nodeid) {
ks_log(KS_LOG_DEBUG, "Session (%s) authorize request missing 'requester-nodeid'\n", blade_session_id_get(bs));
@@ -850,7 +1088,7 @@ ks_bool_t blade_rpcauthorize_request_handler(blade_rpc_request_t *brpcreq, void
}
}
- if (!blade_upstreammgr_masterid_compare(bh->upstreammgr, req_params_responder_nodeid)) {
+ if (!blade_routemgr_master_check(bh->routemgr, req_params_responder_nodeid)) {
ks_log(KS_LOG_DEBUG, "Session (%s) authorize request invalid 'responder-nodeid' (%s)\n", blade_session_id_get(bs), req_params_responder_nodeid);
blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Invalid params responder-nodeid");
blade_session_send(bs, res, NULL, NULL);
@@ -863,7 +1101,7 @@ ks_bool_t blade_rpcauthorize_request_handler(blade_rpc_request_t *brpcreq, void
blade_rpc_response_raw_create(&res, &res_result, blade_rpc_request_messageid_get(brpcreq));
cJSON_ArrayForEach(channel, req_params_channels) {
- if (blade_mastermgr_realm_protocol_channel_authorize(bh->mastermgr, remove, req_params_realm, req_params_protocol, channel->valuestring, req_params_requester_nodeid, req_params_authorized_nodeid) == KS_STATUS_SUCCESS) {
+ if (blade_mastermgr_protocol_channel_authorize(bh->mastermgr, remove, req_params_protocol, channel->valuestring, req_params_requester_nodeid, req_params_authorized_nodeid) == KS_STATUS_SUCCESS) {
if (remove) {
if (!res_result_unauthorized_channels) res_result_unauthorized_channels = cJSON_CreateArray();
cJSON_AddItemToArray(res_result_unauthorized_channels, cJSON_CreateString(channel->valuestring));
@@ -878,7 +1116,6 @@ ks_bool_t blade_rpcauthorize_request_handler(blade_rpc_request_t *brpcreq, void
}
cJSON_AddStringToObject(res_result, "protocol", req_params_protocol);
- cJSON_AddStringToObject(res_result, "realm", req_params_realm);
cJSON_AddStringToObject(res_result, "authorized-nodeid", req_params_authorized_nodeid);
cJSON_AddStringToObject(res_result, "requester-nodeid", req_params_requester_nodeid);
cJSON_AddStringToObject(res_result, "responder-nodeid", req_params_responder_nodeid);
@@ -890,7 +1127,7 @@ ks_bool_t blade_rpcauthorize_request_handler(blade_rpc_request_t *brpcreq, void
blade_session_send(bs, res, NULL, NULL);
if (res_result_unauthorized_channels) {
- blade_handle_rpcsubscribe_raw(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_REMOVE, req_params_protocol, req_params_realm, res_result_unauthorized_channels, req_params_authorized_nodeid, KS_TRUE, NULL, NULL);
+ blade_handle_rpcsubscribe_raw(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_REMOVE, req_params_protocol, res_result_unauthorized_channels, req_params_authorized_nodeid, KS_TRUE, NULL, NULL);
}
done:
@@ -906,44 +1143,32 @@ done:
// @todo discuss system to support caching locate results, and internally subscribing to receive event updates related to protocols which have been located
// to ensure local caches remain synced when protocol controllers change, but this requires additional filters for event propagating to avoid broadcasting
// every protocol update to everyone which may actually be a better way than an explicit locate request
-KS_DECLARE(ks_status_t) blade_handle_rpclocate(blade_handle_t *bh, const char *protocol, const char *realm, blade_rpc_response_callback_t callback, void *data)
+KS_DECLARE(ks_status_t) blade_handle_rpclocate(blade_handle_t *bh, const char *protocol, blade_rpc_response_callback_t callback, void *data)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_session_t *bs = NULL;
- ks_pool_t *pool = NULL;
cJSON *req = NULL;
cJSON *req_params = NULL;
- const char *id = NULL;
ks_assert(bh);
ks_assert(protocol);
- ks_assert(realm);
- if (!(bs = blade_upstreammgr_session_get(bh->upstreammgr))) {
+ if (!(bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
ret = KS_STATUS_DISCONNECTED;
goto done;
}
- pool = ks_pool_get(bh);
- ks_assert(pool);
-
- blade_rpc_request_raw_create(pool, &req, &req_params, NULL, "blade.locate");
+ blade_rpc_request_raw_create(ks_pool_get(bh), &req, &req_params, NULL, "blade.locate");
// fill in the req_params
cJSON_AddStringToObject(req_params, "protocol", protocol);
- cJSON_AddStringToObject(req_params, "realm", realm);
- blade_upstreammgr_localid_copy(bh->upstreammgr, pool, &id);
- ks_assert(id);
+ blade_routemgr_local_pack(bh->routemgr, req_params, "requester-nodeid");
- cJSON_AddStringToObject(req_params, "requester-nodeid", id);
- ks_pool_free(&id);
-
- blade_upstreammgr_masterid_copy(bh->upstreammgr, pool, &id);
- ks_assert(id);
-
- cJSON_AddStringToObject(req_params, "responder-nodeid", id);
- ks_pool_free(&id);
+ if (!blade_routemgr_master_pack(bh->routemgr, req_params, "responder-nodeid")) {
+ ret = KS_STATUS_DISCONNECTED;
+ goto done;
+ }
ks_log(KS_LOG_DEBUG, "Session (%s) locate request started\n", blade_session_id_get(bs));
@@ -964,7 +1189,6 @@ ks_bool_t blade_rpclocate_request_handler(blade_rpc_request_t *brpcreq, void *da
cJSON *req = NULL;
cJSON *req_params = NULL;
const char *req_params_protocol = NULL;
- const char *req_params_realm = NULL;
const char *req_params_requester_nodeid = NULL;
const char *req_params_responder_nodeid = NULL;
cJSON *res = NULL;
@@ -999,16 +1223,6 @@ ks_bool_t blade_rpclocate_request_handler(blade_rpc_request_t *brpcreq, void *da
goto done;
}
- req_params_realm = cJSON_GetObjectCstr(req_params, "realm");
- if (!req_params_realm) {
- ks_log(KS_LOG_DEBUG, "Session (%s) locate request missing 'realm'\n", blade_session_id_get(bs));
- blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params realm");
- blade_session_send(bs, res, NULL, NULL);
- goto done;
- }
-
- // @todo confirm the realm is permitted for the session, this gets complicated with subdomains, skipping for now
-
req_params_requester_nodeid = cJSON_GetObjectCstr(req_params, "requester-nodeid");
if (!req_params_requester_nodeid) {
ks_log(KS_LOG_DEBUG, "Session (%s) locate request missing 'requester-nodeid'\n", blade_session_id_get(bs));
@@ -1025,7 +1239,7 @@ ks_bool_t blade_rpclocate_request_handler(blade_rpc_request_t *brpcreq, void *da
goto done;
}
- if (!blade_upstreammgr_masterid_compare(bh->upstreammgr, req_params_responder_nodeid)) {
+ if (!blade_routemgr_master_check(bh->routemgr, req_params_responder_nodeid)) {
ks_log(KS_LOG_DEBUG, "Session (%s) locate request invalid 'responder-nodeid' (%s)\n", blade_session_id_get(bs), req_params_responder_nodeid);
blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Invalid params responder-nodeid");
blade_session_send(bs, res, NULL, NULL);
@@ -1034,7 +1248,7 @@ ks_bool_t blade_rpclocate_request_handler(blade_rpc_request_t *brpcreq, void *da
ks_log(KS_LOG_DEBUG, "Session (%s) locate request (%s to %s) processing\n", blade_session_id_get(bs), req_params_requester_nodeid, req_params_responder_nodeid);
- bp = blade_mastermgr_realm_protocol_lookup(bh->mastermgr, req_params_realm, req_params_protocol, KS_FALSE);
+ bp = blade_mastermgr_protocol_lookup(bh->mastermgr, req_params_protocol, KS_FALSE);
if (bp) {
res_result_controllers = blade_protocol_controller_pack(bp);
blade_protocol_read_unlock(bp);
@@ -1045,7 +1259,6 @@ ks_bool_t blade_rpclocate_request_handler(blade_rpc_request_t *brpcreq, void *da
blade_rpc_response_raw_create(&res, &res_result, blade_rpc_request_messageid_get(brpcreq));
cJSON_AddStringToObject(res_result, "protocol", req_params_protocol);
- cJSON_AddStringToObject(res_result, "realm", req_params_realm);
cJSON_AddStringToObject(res_result, "requester-nodeid", req_params_requester_nodeid);
cJSON_AddStringToObject(res_result, "responder-nodeid", req_params_responder_nodeid);
if (res_result_controllers) cJSON_AddItemToObject(res_result, "controllers", res_result_controllers);
@@ -1063,42 +1276,31 @@ done:
// blade.execute request generator
-KS_DECLARE(ks_status_t) blade_handle_rpcexecute(blade_handle_t *bh, const char *nodeid, const char *method, const char *protocol, const char *realm, cJSON *params, blade_rpc_response_callback_t callback, void *data)
+KS_DECLARE(ks_status_t) blade_handle_rpcexecute(blade_handle_t *bh, const char *nodeid, const char *method, const char *protocol, cJSON *params, blade_rpc_response_callback_t callback, void *data)
{
ks_status_t ret = KS_STATUS_SUCCESS;
blade_session_t *bs = NULL;
- ks_pool_t *pool = NULL;
cJSON *req = NULL;
cJSON *req_params = NULL;
- const char *localid = NULL;
ks_assert(bh);
ks_assert(nodeid);
ks_assert(method);
ks_assert(protocol);
- ks_assert(realm);
if (!(bs = blade_routemgr_route_lookup(blade_handle_routemgr_get(bh), nodeid))) {
- if (!(bs = blade_upstreammgr_session_get(bh->upstreammgr))) {
+ if (!(bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
ret = KS_STATUS_DISCONNECTED;
goto done;
}
}
- pool = ks_pool_get(bh);
- ks_assert(pool);
-
- blade_rpc_request_raw_create(pool, &req, &req_params, NULL, "blade.execute");
+ blade_rpc_request_raw_create(ks_pool_get(bh), &req, &req_params, NULL, "blade.execute");
cJSON_AddStringToObject(req_params, "method", method);
cJSON_AddStringToObject(req_params, "protocol", protocol);
- cJSON_AddStringToObject(req_params, "realm", realm);
- blade_upstreammgr_localid_copy(bh->upstreammgr, pool, &localid);
- ks_assert(localid);
-
- cJSON_AddStringToObject(req_params, "requester-nodeid", localid);
- ks_pool_free(&localid);
+ blade_routemgr_local_pack(bh->routemgr, req_params, "requester-nodeid");
cJSON_AddStringToObject(req_params, "responder-nodeid", nodeid);
@@ -1125,7 +1327,6 @@ ks_bool_t blade_rpcexecute_request_handler(blade_rpc_request_t *brpcreq, void *d
cJSON *req_params = NULL;
const char *req_params_method = NULL;
const char *req_params_protocol = NULL;
- const char *req_params_realm = NULL;
const char *req_params_requester_nodeid = NULL;
const char *req_params_responder_nodeid = NULL;
blade_rpc_t *brpc = NULL;
@@ -1167,16 +1368,6 @@ ks_bool_t blade_rpcexecute_request_handler(blade_rpc_request_t *brpcreq, void *d
goto done;
}
- req_params_realm = cJSON_GetObjectCstr(req_params, "realm");
- if (!req_params_realm) {
- ks_log(KS_LOG_DEBUG, "Session (%s) execute request missing 'realm'\n", blade_session_id_get(bs));
- blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params realm");
- blade_session_send(bs, res, NULL, NULL);
- goto done;
- }
-
- // @todo confirm the realm is permitted for the session, this gets complicated with subdomains, skipping for now
-
req_params_requester_nodeid = cJSON_GetObjectCstr(req_params, "requester-nodeid");
if (!req_params_requester_nodeid) {
ks_log(KS_LOG_DEBUG, "Session (%s) execute request missing 'requester-nodeid'\n", blade_session_id_get(bs));
@@ -1197,7 +1388,7 @@ ks_bool_t blade_rpcexecute_request_handler(blade_rpc_request_t *brpcreq, void *d
// @todo pull out nested params block if it exists and check against schema later, so blade_rpc_t should be able to carry a schema with it, even though blade.xxx may not associate one
- brpc = blade_rpcmgr_protocolrpc_lookup(blade_handle_rpcmgr_get(bh), req_params_method, req_params_protocol, req_params_realm);
+ brpc = blade_rpcmgr_protocolrpc_lookup(blade_handle_rpcmgr_get(bh), req_params_method, req_params_protocol);
if (!brpc) {
ks_log(KS_LOG_DEBUG, "Session (%s) execute request unknown method\n", blade_session_id_get(bs));
blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Unknown params method");
@@ -1295,7 +1486,6 @@ KS_DECLARE(void) blade_rpcexecute_response_send(blade_rpc_request_t *brpcreq, cJ
cJSON *req_params = NULL;
//const char *req_params_method = NULL;
const char *req_params_protocol = NULL;
- const char *req_params_realm = NULL;
const char *req_params_requester_nodeid = NULL;
const char *req_params_responder_nodeid = NULL;
cJSON *res = NULL;
@@ -1318,9 +1508,6 @@ KS_DECLARE(void) blade_rpcexecute_response_send(blade_rpc_request_t *brpcreq, cJ
req_params_protocol = cJSON_GetObjectCstr(req_params, "protocol");
ks_assert(req_params_protocol);
- req_params_realm = cJSON_GetObjectCstr(req_params, "realm");
- ks_assert(req_params_realm);
-
req_params_requester_nodeid = cJSON_GetObjectCstr(req_params, "requester-nodeid");
ks_assert(req_params_requester_nodeid);
@@ -1331,7 +1518,6 @@ KS_DECLARE(void) blade_rpcexecute_response_send(blade_rpc_request_t *brpcreq, cJ
blade_rpc_response_raw_create(&res, &res_result, blade_rpc_request_messageid_get(brpcreq));
cJSON_AddStringToObject(res_result, "protocol", req_params_protocol);
- cJSON_AddStringToObject(res_result, "realm", req_params_realm);
cJSON_AddStringToObject(res_result, "requester-nodeid", req_params_requester_nodeid);
cJSON_AddStringToObject(res_result, "responder-nodeid", req_params_responder_nodeid);
if (result) cJSON_AddItemToObject(res_result, "result", cJSON_Duplicate(result, 1));
@@ -1355,7 +1541,7 @@ static void blade_rpcsubscribe_data_cleanup(void *ptr, void *arg, ks_pool_cleanu
case KS_MPCL_ANNOUNCE:
break;
case KS_MPCL_TEARDOWN:
- if (brpcsd->relayed_messageid) ks_pool_free(&brpcsd->relayed_messageid);
+ if (brpcsd->original_requestid) ks_pool_free(&brpcsd->original_requestid);
break;
case KS_MPCL_DESTROY:
break;
@@ -1366,7 +1552,6 @@ static void blade_rpcsubscribe_data_cleanup(void *ptr, void *arg, ks_pool_cleanu
KS_DECLARE(ks_status_t) blade_handle_rpcsubscribe(blade_handle_t *bh,
blade_rpcsubscribe_command_t command,
const char *protocol,
- const char *realm,
cJSON *channels,
blade_rpc_response_callback_t callback,
void *data,
@@ -1374,38 +1559,33 @@ KS_DECLARE(ks_status_t) blade_handle_rpcsubscribe(blade_handle_t *bh,
void *channel_data)
{
ks_status_t ret = KS_STATUS_SUCCESS;
- ks_pool_t *pool = NULL;
blade_session_t *bs = NULL;
const char *localid = NULL;
blade_rpcsubscribe_data_t *temp_data = NULL;
ks_assert(bh);
ks_assert(protocol);
- ks_assert(realm);
ks_assert(channels);
- pool = ks_pool_get(bh);
- ks_assert(pool);
-
// @note this is always produced by a subscriber, and sent upstream, master will only use the internal raw call
- if (!(bs = blade_upstreammgr_session_get(bh->upstreammgr))) {
+ if (!(bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
ret = KS_STATUS_DISCONNECTED;
goto done;
}
- blade_upstreammgr_localid_copy(bh->upstreammgr, ks_pool_get(bh), &localid);
+ blade_routemgr_local_copy(bh->routemgr, &localid);
ks_assert(localid);
// @note since this is allocated in the handle's pool, if the handle is shutdown during a pending request, then the data
// memory will be cleaned up with the handle, otherwise should be cleaned up in the response callback
- temp_data = (blade_rpcsubscribe_data_t *)ks_pool_alloc(pool, sizeof(blade_rpcsubscribe_data_t));
+ temp_data = (blade_rpcsubscribe_data_t *)ks_pool_alloc(ks_pool_get(bh), sizeof(blade_rpcsubscribe_data_t));
temp_data->original_callback = callback;
temp_data->original_data = data;
temp_data->channel_callback = channel_callback;
temp_data->channel_data = channel_data;
ks_pool_set_cleanup(temp_data, NULL, blade_rpcsubscribe_data_cleanup);
- ret = blade_handle_rpcsubscribe_raw(bh, command, protocol, realm, channels, localid, KS_FALSE, blade_rpcsubscribe_response_handler, temp_data);
+ ret = blade_handle_rpcsubscribe_raw(bh, command, protocol, channels, localid, KS_FALSE, blade_rpcsubscribe_response_handler, temp_data);
ks_pool_free(&localid);
@@ -1418,7 +1598,6 @@ done:
ks_status_t blade_handle_rpcsubscribe_raw(blade_handle_t *bh,
blade_rpcsubscribe_command_t command,
const char *protocol,
- const char *realm,
cJSON *channels,
const char *subscriber,
ks_bool_t downstream,
@@ -1433,7 +1612,6 @@ ks_status_t blade_handle_rpcsubscribe_raw(blade_handle_t *bh,
ks_assert(bh);
ks_assert(protocol);
- ks_assert(realm);
ks_assert(channels);
ks_assert(subscriber);
@@ -1448,7 +1626,7 @@ ks_status_t blade_handle_rpcsubscribe_raw(blade_handle_t *bh,
goto done;
}
}
- else if (!(bs = blade_upstreammgr_session_get(bh->upstreammgr))) {
+ else if (!(bs = blade_routemgr_upstream_lookup(bh->routemgr))) {
ret = KS_STATUS_DISCONNECTED;
goto done;
}
@@ -1459,7 +1637,7 @@ ks_status_t blade_handle_rpcsubscribe_raw(blade_handle_t *bh,
if (command == BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_REMOVE) {
cJSON *channel = NULL;
cJSON_ArrayForEach(channel, channels) {
- blade_subscriptionmgr_subscriber_remove(bh->subscriptionmgr, NULL, protocol, realm, channel->valuestring, subscriber);
+ blade_subscriptionmgr_subscriber_remove(bh->subscriptionmgr, NULL, protocol, channel->valuestring, subscriber);
}
}
@@ -1467,7 +1645,6 @@ ks_status_t blade_handle_rpcsubscribe_raw(blade_handle_t *bh,
cJSON_AddNumberToObject(req_params, "command", command);
cJSON_AddStringToObject(req_params, "protocol", protocol);
- cJSON_AddStringToObject(req_params, "realm", realm);
cJSON_AddStringToObject(req_params, "subscriber-nodeid", subscriber);
if (downstream) cJSON_AddTrueToObject(req_params, "downstream");
cJSON_AddItemToObject(req_params, "channels", cJSON_Duplicate(channels, 1));
@@ -1494,7 +1671,6 @@ ks_bool_t blade_rpcsubscribe_request_handler(blade_rpc_request_t *brpcreq, void
cJSON *req_params_command = NULL;
blade_rpcsubscribe_command_t command = BLADE_RPCSUBSCRIBE_COMMAND_NONE;
const char *req_params_protocol = NULL;
- const char *req_params_realm = NULL;
const char *req_params_subscriber_nodeid = NULL;
cJSON *req_params_downstream = NULL;
ks_bool_t downstream = KS_FALSE;
@@ -1549,14 +1725,6 @@ ks_bool_t blade_rpcsubscribe_request_handler(blade_rpc_request_t *brpcreq, void
goto done;
}
- req_params_realm = cJSON_GetObjectCstr(req_params, "realm");
- if (!req_params_realm) {
- ks_log(KS_LOG_DEBUG, "Session (%s) subscribe request missing 'realm'\n", blade_session_id_get(bs));
- blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params realm");
- blade_session_send(bs, res, NULL, NULL);
- goto done;
- }
-
req_params_subscriber_nodeid = cJSON_GetObjectCstr(req_params, "subscriber-nodeid");
if (!req_params_subscriber_nodeid) {
ks_log(KS_LOG_DEBUG, "Session (%s) subscribe request missing 'subscriber-nodeid'\n", blade_session_id_get(bs));
@@ -1579,26 +1747,23 @@ ks_bool_t blade_rpcsubscribe_request_handler(blade_rpc_request_t *brpcreq, void
goto done;
}
- // @todo confirm the realm is permitted for the session, this gets complicated with subdomains, skipping for now
-
ks_log(KS_LOG_DEBUG, "Session (%s) subscribe request processing\n", blade_session_id_get(bs));
- masterlocal = blade_upstreammgr_masterlocal(blade_handle_upstreammgr_get(bh));
+ masterlocal = blade_routemgr_master_local(blade_handle_routemgr_get(bh));
- if (masterlocal || blade_upstreammgr_localid_compare(blade_handle_upstreammgr_get(bh), req_params_subscriber_nodeid)) {
+ if (masterlocal || blade_routemgr_local_check(blade_handle_routemgr_get(bh), req_params_subscriber_nodeid)) {
// @note This is normally handled by blade_handle_rpcsubscribe_raw() to ensure authorization removals are processed during the request path
// including on the node they start on, whether that is the master or the subscriber
if (command == BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_REMOVE) {
cJSON *channel = NULL;
cJSON_ArrayForEach(channel, req_params_channels) {
- blade_subscriptionmgr_subscriber_remove(bh->subscriptionmgr, NULL, req_params_protocol, req_params_realm, channel->valuestring, req_params_subscriber_nodeid);
+ blade_subscriptionmgr_subscriber_remove(bh->subscriptionmgr, NULL, req_params_protocol, channel->valuestring, req_params_subscriber_nodeid);
}
}
blade_rpc_response_raw_create(&res, &res_result, blade_rpc_request_messageid_get(brpcreq));
cJSON_AddStringToObject(res_result, "protocol", req_params_protocol);
- cJSON_AddStringToObject(res_result, "realm", req_params_realm);
cJSON_AddStringToObject(res_result, "subscriber-nodeid", req_params_subscriber_nodeid);
if (downstream) cJSON_AddTrueToObject(res_result, "downstream");
@@ -1607,8 +1772,8 @@ ks_bool_t blade_rpcsubscribe_request_handler(blade_rpc_request_t *brpcreq, void
cJSON *channel = NULL;
cJSON_ArrayForEach(channel, req_params_channels) {
- if (blade_mastermgr_realm_protocol_channel_authorization_verify(bh->mastermgr, req_params_realm, req_params_protocol, channel->valuestring, req_params_subscriber_nodeid)) {
- blade_subscriptionmgr_subscriber_add(bh->subscriptionmgr, NULL, req_params_protocol, req_params_realm, channel->valuestring, req_params_subscriber_nodeid);
+ if (blade_mastermgr_protocol_channel_authorization_verify(bh->mastermgr, req_params_protocol, channel->valuestring, req_params_subscriber_nodeid)) {
+ blade_subscriptionmgr_subscriber_add(bh->subscriptionmgr, NULL, req_params_protocol, channel->valuestring, req_params_subscriber_nodeid);
if (!res_result_subscribe_channels) res_result_subscribe_channels = cJSON_CreateArray();
cJSON_AddItemToArray(res_result_subscribe_channels, cJSON_CreateString(channel->valuestring));
} else {
@@ -1627,10 +1792,10 @@ ks_bool_t blade_rpcsubscribe_request_handler(blade_rpc_request_t *brpcreq, void
blade_session_send(bs, res, NULL, NULL);
} else {
blade_rpcsubscribe_data_t *temp_data = (blade_rpcsubscribe_data_t *)ks_pool_alloc(pool, sizeof(blade_rpcsubscribe_data_t));
- temp_data->relayed_messageid = ks_pstrdup(pool, blade_rpc_request_messageid_get(brpcreq));
+ temp_data->original_requestid = ks_pstrdup(pool, blade_rpc_request_messageid_get(brpcreq));
ks_pool_set_cleanup(temp_data, NULL, blade_rpcsubscribe_data_cleanup);
- blade_handle_rpcsubscribe_raw(bh, command, req_params_protocol, req_params_realm, req_params_channels, req_params_subscriber_nodeid, downstream, blade_rpcsubscribe_response_handler, temp_data);
+ blade_handle_rpcsubscribe_raw(bh, command, req_params_protocol, req_params_channels, req_params_subscriber_nodeid, downstream, blade_rpcsubscribe_response_handler, temp_data);
}
done:
@@ -1651,7 +1816,6 @@ ks_bool_t blade_rpcsubscribe_response_handler(blade_rpc_response_t *brpcres, voi
cJSON *res = NULL;
cJSON *res_result = NULL;
const char *res_result_protocol = NULL;
- const char *res_result_realm = NULL;
const char *res_result_subscriber_nodeid = NULL;
cJSON *res_result_downstream = NULL;
ks_bool_t downstream = KS_FALSE;
@@ -1677,7 +1841,7 @@ ks_bool_t blade_rpcsubscribe_response_handler(blade_rpc_response_t *brpcres, voi
goto done;
}
- // @todo the following 3 fields, protocol, realm, and subscriber-nodeid may not be required to carry in the response as they could be
+ // @todo the following 2 fields, protocol, and subscriber-nodeid may not be required to carry in the response as they could be
// obtained from the original request tied to the response, change this later
res_result_protocol = cJSON_GetObjectCstr(res_result, "protocol");
if (!res_result_protocol) {
@@ -1685,12 +1849,6 @@ ks_bool_t blade_rpcsubscribe_response_handler(blade_rpc_response_t *brpcres, voi
goto done;
}
- res_result_realm = cJSON_GetObjectCstr(res_result, "realm");
- if (!res_result_realm) {
- ks_log(KS_LOG_DEBUG, "Session (%s) subscribe response missing 'realm'\n", blade_session_id_get(bs));
- goto done;
- }
-
res_result_subscriber_nodeid = cJSON_GetObjectCstr(res_result, "subscriber-nodeid");
if (!res_result_subscriber_nodeid) {
ks_log(KS_LOG_DEBUG, "Session (%s) subscribe response missing 'subscriber-nodeid'\n", blade_session_id_get(bs));
@@ -1710,7 +1868,7 @@ ks_bool_t blade_rpcsubscribe_response_handler(blade_rpc_response_t *brpcres, voi
blade_subscription_t *bsub = NULL;
cJSON_ArrayForEach(channel, res_result_subscribe_channels) {
- blade_subscriptionmgr_subscriber_add(bh->subscriptionmgr, &bsub, res_result_protocol, res_result_realm, channel->valuestring, res_result_subscriber_nodeid);
+ blade_subscriptionmgr_subscriber_add(bh->subscriptionmgr, &bsub, res_result_protocol, channel->valuestring, res_result_subscriber_nodeid);
// @note these will only get assigned on the last response, received by the subscriber
if (temp_data && temp_data->channel_callback) blade_subscription_callback_set(bsub, temp_data->channel_callback);
if (temp_data && temp_data->channel_data) blade_subscription_callback_data_set(bsub, temp_data->channel_data);
@@ -1720,10 +1878,10 @@ ks_bool_t blade_rpcsubscribe_response_handler(blade_rpc_response_t *brpcres, voi
// @note this will only happen on the last response, received by the subscriber
if (temp_data && temp_data->original_callback) ret = temp_data->original_callback(brpcres, temp_data->original_data);
- if (temp_data && temp_data->relayed_messageid) {
+ if (temp_data && temp_data->original_requestid) {
blade_session_t *relay = NULL;
if (downstream) {
- if (!(relay = blade_upstreammgr_session_get(bh->upstreammgr))) {
+ if (!(relay = blade_routemgr_upstream_lookup(bh->routemgr))) {
goto done;
}
} else {
@@ -1732,10 +1890,9 @@ ks_bool_t blade_rpcsubscribe_response_handler(blade_rpc_response_t *brpcres, voi
}
}
- blade_rpc_response_raw_create(&res, &res_result, temp_data->relayed_messageid);
+ blade_rpc_response_raw_create(&res, &res_result, temp_data->original_requestid);
cJSON_AddStringToObject(res_result, "protocol", res_result_protocol);
- cJSON_AddStringToObject(res_result, "realm", res_result_realm);
cJSON_AddStringToObject(res_result, "subscriber-nodeid", res_result_subscriber_nodeid);
if (downstream) cJSON_AddTrueToObject(res_result, "downstream");
if (res_result_subscribe_channels) cJSON_AddItemToObject(res_result, "subscribe-channels", cJSON_Duplicate(res_result_subscribe_channels, 1));
@@ -1756,15 +1913,14 @@ done:
// blade.broadcast request generator
-KS_DECLARE(ks_status_t) blade_handle_rpcbroadcast(blade_handle_t *bh, const char *protocol, const char *realm, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data)
+KS_DECLARE(ks_status_t) blade_handle_rpcbroadcast(blade_handle_t *bh, const char *protocol, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data)
{
ks_status_t ret = KS_STATUS_SUCCESS;
ks_assert(bh);
ks_assert(protocol);
- ks_assert(realm);
- ret = blade_subscriptionmgr_broadcast(bh->subscriptionmgr, BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, protocol, realm, channel, event, params, callback, data);
+ ret = blade_subscriptionmgr_broadcast(bh->subscriptionmgr, BLADE_RPCBROADCAST_COMMAND_EVENT, NULL, protocol, channel, event, params, callback, data);
// @todo must check if the local node is also subscribed to receive the event, this is a special edge case which has some extra considerations
// if the local node is subscribed to receive the event, it should be received here as a special case, otherwise the broadcast request handler
@@ -1786,7 +1942,6 @@ ks_bool_t blade_rpcbroadcast_request_handler(blade_rpc_request_t *brpcreq, void
cJSON *req_params_command = NULL;
blade_rpcbroadcast_command_t command = BLADE_RPCBROADCAST_COMMAND_NONE;
const char *req_params_protocol = NULL;
- const char *req_params_realm = NULL;
const char *req_params_channel = NULL;
const char *req_params_event = NULL;
cJSON *req_params_params = NULL;
@@ -1822,14 +1977,6 @@ ks_bool_t blade_rpcbroadcast_request_handler(blade_rpc_request_t *brpcreq, void
goto done;
}
- req_params_realm = cJSON_GetObjectCstr(req_params, "realm");
- if (!req_params_realm) {
- ks_log(KS_LOG_DEBUG, "Session (%s) broadcast request missing 'realm'\n", blade_session_id_get(bs));
- blade_rpc_error_raw_create(&res, NULL, blade_rpc_request_messageid_get(brpcreq), -32602, "Missing params realm");
- blade_session_send(bs, res, NULL, NULL);
- goto done;
- }
-
req_params_command = cJSON_GetObjectItem(req_params, "command");
if (!req_params_command) {
ks_log(KS_LOG_DEBUG, "Session (%s) broadcast request missing 'command'\n", blade_session_id_get(bs));
@@ -1862,17 +2009,14 @@ ks_bool_t blade_rpcbroadcast_request_handler(blade_rpc_request_t *brpcreq, void
req_params_params = cJSON_GetObjectItem(req_params, "params");
- blade_subscriptionmgr_broadcast(bh->subscriptionmgr, command, blade_session_id_get(bs), req_params_protocol, req_params_realm, req_params_channel, req_params_event, req_params_params, NULL, NULL);
+ blade_subscriptionmgr_broadcast(bh->subscriptionmgr, command, blade_session_id_get(bs), req_params_protocol, req_params_channel, req_params_event, req_params_params, NULL, NULL);
if (command == BLADE_RPCBROADCAST_COMMAND_EVENT) {
- bsub = blade_subscriptionmgr_subscription_lookup(bh->subscriptionmgr, req_params_protocol, req_params_realm, req_params_channel);
+ bsub = blade_subscriptionmgr_subscription_lookup(bh->subscriptionmgr, req_params_protocol, req_params_channel);
if (bsub) {
const char *localid = NULL;
- ks_pool_t *pool = NULL;
- pool = ks_pool_get(bh);
-
- blade_upstreammgr_localid_copy(bh->upstreammgr, pool, &localid);
+ blade_routemgr_local_copy(bh->routemgr, &localid);
ks_assert(localid);
if (ks_hash_search(blade_subscription_subscribers_get(bsub), (void *)localid, KS_UNLOCKED)) {
@@ -1888,7 +2032,6 @@ ks_bool_t blade_rpcbroadcast_request_handler(blade_rpc_request_t *brpcreq, void
// @todo this is not neccessary, can obtain this from the original request
cJSON_AddStringToObject(res_result, "protocol", req_params_protocol);
- cJSON_AddStringToObject(res_result, "realm", req_params_realm);
if (req_params_channel) cJSON_AddStringToObject(res_result, "channel", req_params_channel);
if (req_params_event) cJSON_AddStringToObject(res_result, "event", req_params_event);
@@ -1903,64 +2046,56 @@ done:
return ret;
}
-KS_DECLARE(const char *) blade_rpcbroadcast_request_realm_get(blade_rpc_request_t *brpcreq)
-{
- cJSON *req = NULL;
- const char *req_realm = NULL;
-
- ks_assert(brpcreq);
-
- req = blade_rpc_request_message_get(brpcreq);
- ks_assert(req);
-
- req_realm = cJSON_GetObjectCstr(req, "realm");
-
- return req_realm;
-}
KS_DECLARE(const char *) blade_rpcbroadcast_request_protocol_get(blade_rpc_request_t *brpcreq)
{
cJSON *req = NULL;
- const char *req_protocol = NULL;
+ cJSON *req_params = NULL;
+ const char *req_params_protocol = NULL;
ks_assert(brpcreq);
req = blade_rpc_request_message_get(brpcreq);
ks_assert(req);
- req_protocol = cJSON_GetObjectCstr(req, "protocol");
+ req_params = cJSON_GetObjectItem(req, "params");
+ if (req_params) req_params_protocol = cJSON_GetObjectCstr(req_params, "protocol");
- return req_protocol;
+ return req_params_protocol;
}
KS_DECLARE(const char *) blade_rpcbroadcast_request_channel_get(blade_rpc_request_t *brpcreq)
{
cJSON *req = NULL;
- const char *req_channel = NULL;
+ cJSON *req_params = NULL;
+ const char *req_params_channel = NULL;
ks_assert(brpcreq);
req = blade_rpc_request_message_get(brpcreq);
ks_assert(req);
- req_channel = cJSON_GetObjectCstr(req, "channel");
+ req_params = cJSON_GetObjectItem(req, "params");
+ if (req_params) req_params_channel = cJSON_GetObjectCstr(req_params, "channel");
- return req_channel;
+ return req_params_channel;
}
KS_DECLARE(const char *) blade_rpcbroadcast_request_event_get(blade_rpc_request_t *brpcreq)
{
cJSON *req = NULL;
- const char *req_event = NULL;
+ cJSON *req_params = NULL;
+ const char *req_params_event = NULL;
ks_assert(brpcreq);
req = blade_rpc_request_message_get(brpcreq);
ks_assert(req);
- req_event = cJSON_GetObjectCstr(req, "event");
+ req_params = cJSON_GetObjectItem(req, "params");
+ if (req_params) req_params_event = cJSON_GetObjectCstr(req_params, "event");
- return req_event;
+ return req_params_event;
}
KS_DECLARE(cJSON *) blade_rpcbroadcast_request_params_get(blade_rpc_request_t *brpcreq)
diff --git a/libs/libblade/src/blade_subscription.c b/libs/libblade/src/blade_subscription.c
index 153551e771..19c6fdd5d1 100644
--- a/libs/libblade/src/blade_subscription.c
+++ b/libs/libblade/src/blade_subscription.c
@@ -35,7 +35,6 @@
struct blade_subscription_s {
const char *protocol;
- const char *realm;
const char *channel;
ks_hash_t *subscribers;
@@ -55,7 +54,6 @@ static void blade_subscription_cleanup(void *ptr, void *arg, ks_pool_cleanup_act
break;
case KS_MPCL_TEARDOWN:
if (bsub->protocol) ks_pool_free(&bsub->protocol);
- if (bsub->realm) ks_pool_free(&bsub->subscribers);
if (bsub->channel) ks_pool_free(&bsub->channel);
if (bsub->subscribers) ks_hash_destroy(&bsub->subscribers);
break;
@@ -64,19 +62,17 @@ static void blade_subscription_cleanup(void *ptr, void *arg, ks_pool_cleanup_act
}
}
-KS_DECLARE(ks_status_t) blade_subscription_create(blade_subscription_t **bsubP, ks_pool_t *pool, const char *protocol, const char *realm, const char *channel)
+KS_DECLARE(ks_status_t) blade_subscription_create(blade_subscription_t **bsubP, ks_pool_t *pool, const char *protocol, const char *channel)
{
blade_subscription_t *bsub = NULL;
ks_assert(bsubP);
ks_assert(pool);
ks_assert(protocol);
- ks_assert(realm);
ks_assert(channel);
bsub = ks_pool_alloc(pool, sizeof(blade_subscription_t));
bsub->protocol = ks_pstrdup(pool, protocol);
- bsub->realm = ks_pstrdup(pool, realm);
bsub->channel = ks_pstrdup(pool, channel);
ks_hash_create(&bsub->subscribers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
@@ -104,15 +100,6 @@ KS_DECLARE(const char *) blade_subscription_protocol_get(blade_subscription_t *b
ks_assert(bsub);
return bsub->protocol;
-
-}
-
-KS_DECLARE(const char *) blade_subscription_realm_get(blade_subscription_t *bsub)
-{
- ks_assert(bsub);
-
- return bsub->realm;
-
}
KS_DECLARE(const char *) blade_subscription_channel_get(blade_subscription_t *bsub)
@@ -120,7 +107,6 @@ KS_DECLARE(const char *) blade_subscription_channel_get(blade_subscription_t *bs
ks_assert(bsub);
return bsub->channel;
-
}
KS_DECLARE(ks_hash_t *) blade_subscription_subscribers_get(blade_subscription_t *bsub)
@@ -128,7 +114,6 @@ KS_DECLARE(ks_hash_t *) blade_subscription_subscribers_get(blade_subscription_t
ks_assert(bsub);
return bsub->subscribers;
-
}
KS_DECLARE(ks_status_t) blade_subscription_subscribers_add(blade_subscription_t *bsub, const char *nodeid)
diff --git a/libs/libblade/src/blade_subscriptionmgr.c b/libs/libblade/src/blade_subscriptionmgr.c
index e09dabfaa0..64105239cd 100644
--- a/libs/libblade/src/blade_subscriptionmgr.c
+++ b/libs/libblade/src/blade_subscriptionmgr.c
@@ -124,17 +124,16 @@ KS_DECLARE(blade_handle_t *) blade_subscriptionmgr_handle_get(blade_subscription
// return bs;
//}
-KS_DECLARE(blade_subscription_t *) blade_subscriptionmgr_subscription_lookup(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *realm, const char *channel)
+KS_DECLARE(blade_subscription_t *) blade_subscriptionmgr_subscription_lookup(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *channel)
{
blade_subscription_t *bsub = NULL;
char *key = NULL;
ks_assert(bsmgr);
ks_assert(protocol);
- ks_assert(realm);
ks_assert(channel);
- key = ks_psprintf(ks_pool_get(bsmgr), "%s@%s/%s", protocol, realm, channel);
+ key = ks_psprintf(ks_pool_get(bsmgr), "%s:%s", protocol, channel);
bsub = (blade_subscription_t *)ks_hash_search(bsmgr->subscriptions, (void *)key, KS_READLOCKED);
// @todo if (bsub) blade_subscription_read_lock(bsub);
@@ -145,7 +144,7 @@ KS_DECLARE(blade_subscription_t *) blade_subscriptionmgr_subscription_lookup(bla
return bsub;
}
-KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *realm, const char *channel)
+KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *channel)
{
ks_pool_t *pool = NULL;
char *bsub_key = NULL;
@@ -155,12 +154,11 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscrip
ks_assert(bsmgr);
ks_assert(protocol);
- ks_assert(realm);
ks_assert(channel);
pool = ks_pool_get(bsmgr);
- bsub_key = ks_psprintf(pool, "%s@%s/%s", protocol, realm, channel);
+ bsub_key = ks_psprintf(pool, "%s:%s", protocol, channel);
ks_hash_write_lock(bsmgr->subscriptions);
@@ -177,7 +175,7 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscrip
subscriptions = (ks_hash_t *)ks_hash_search(bsmgr->subscriptions_cleanup, key, KS_UNLOCKED);
- ks_log(KS_LOG_DEBUG, "Subscriber Removed: %s from %s\n", key, bsub_key);
+ ks_log(KS_LOG_DEBUG, "Subscriber Removed: %s from protocol %s, channel %s\n", key, protocol, channel);
ks_hash_remove(subscriptions, bsub_key);
if (ks_hash_count(subscriptions) == 0) {
@@ -185,7 +183,7 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscrip
}
}
- ks_log(KS_LOG_DEBUG, "Subscription Removed: %s\n", bsub_key);
+ ks_log(KS_LOG_DEBUG, "Subscription Removed: %s from %s\n", channel, protocol);
ks_hash_remove(bsmgr->subscriptions, (void *)bsub_key);
ks_hash_write_unlock(bsmgr->subscriptions);
@@ -195,7 +193,7 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscrip
return KS_STATUS_SUCCESS;
}
-KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *realm, const char *channel, const char *subscriber)
+KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *channel, const char *subscriber)
{
ks_pool_t *pool = NULL;
char *key = NULL;
@@ -205,20 +203,19 @@ KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr
ks_assert(bsmgr);
ks_assert(protocol);
- ks_assert(realm);
ks_assert(channel);
ks_assert(subscriber);
pool = ks_pool_get(bsmgr);
- key = ks_psprintf(pool, "%s@%s/%s", protocol, realm, channel);
+ key = ks_psprintf(pool, "%s:%s", protocol, channel);
ks_hash_write_lock(bsmgr->subscriptions);
bsub = (blade_subscription_t *)ks_hash_search(bsmgr->subscriptions, (void *)key, KS_UNLOCKED);
if (!bsub) {
- blade_subscription_create(&bsub, pool, protocol, realm, channel);
+ blade_subscription_create(&bsub, pool, protocol, channel);
ks_assert(bsub);
ks_hash_insert(bsmgr->subscriptions, (void *)ks_pstrdup(pool, key), (void *)bsub);
@@ -230,7 +227,7 @@ KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr
ks_hash_create(&bsub_cleanup, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
ks_assert(bsub_cleanup);
- ks_log(KS_LOG_DEBUG, "Subscription Added: %s\n", key);
+ ks_log(KS_LOG_DEBUG, "Subscription Added: %s to %s\n", channel, protocol);
ks_hash_insert(bsmgr->subscriptions_cleanup, (void *)ks_pstrdup(pool, subscriber), (void *)bsub_cleanup);
}
ks_hash_insert(bsub_cleanup, (void *)ks_pstrdup(pool, key), (void *)KS_TRUE);
@@ -239,7 +236,7 @@ KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr
ks_hash_write_unlock(bsmgr->subscriptions);
- ks_log(KS_LOG_DEBUG, "Subscriber Added: %s to %s\n", subscriber, key);
+ ks_log(KS_LOG_DEBUG, "Subscriber Added: %s to protocol %s, channel %s\n", subscriber, protocol, channel);
ks_pool_free(&key);
@@ -248,7 +245,7 @@ KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr
return propagate;
}
-KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_remove(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *realm, const char *channel, const char *subscriber)
+KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_remove(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *channel, const char *subscriber)
{
char *key = NULL;
blade_subscription_t *bsub = NULL;
@@ -257,11 +254,10 @@ KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_remove(blade_subscription
ks_assert(bsmgr);
ks_assert(protocol);
- ks_assert(realm);
ks_assert(channel);
ks_assert(subscriber);
- key = ks_psprintf(ks_pool_get(bsmgr), "%s@%s/%s", protocol, realm, channel);
+ key = ks_psprintf(ks_pool_get(bsmgr), "%s:%s", protocol, channel);
ks_hash_write_lock(bsmgr->subscriptions);
@@ -276,11 +272,11 @@ KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_remove(blade_subscription
ks_hash_remove(bsmgr->subscriptions_cleanup, (void *)subscriber);
}
- ks_log(KS_LOG_DEBUG, "Subscriber Removed: %s from %s\n", subscriber, key);
+ ks_log(KS_LOG_DEBUG, "Subscriber Removed: %s from protocol %s, channel %s\n", subscriber, protocol, channel);
blade_subscription_subscribers_remove(bsub, subscriber);
if (ks_hash_count(blade_subscription_subscribers_get(bsub)) == 0) {
- ks_log(KS_LOG_DEBUG, "Subscription Removed: %s\n", key);
+ ks_log(KS_LOG_DEBUG, "Subscription Removed: %s from %s\n", channel, protocol);
ks_hash_remove(bsmgr->subscriptions, (void *)key);
propagate = KS_TRUE;
}
@@ -309,7 +305,6 @@ KS_DECLARE(void) blade_subscriptionmgr_purge(blade_subscriptionmgr_t *bsmgr, con
while (!unsubbed) {
ks_hash_t *subscriptions = NULL;
const char *protocol = NULL;
- const char *realm = NULL;
const char *channel = NULL;
ks_hash_read_lock(bsmgr->subscriptions);
@@ -330,22 +325,20 @@ KS_DECLARE(void) blade_subscriptionmgr_purge(blade_subscriptionmgr_t *bsmgr, con
// @note allocate these to avoid lifecycle issues when the last subscriber is removed causing the subscription to be removed
protocol = ks_pstrdup(pool, blade_subscription_protocol_get(bsub));
- realm = ks_pstrdup(pool, blade_subscription_realm_get(bsub));
channel = ks_pstrdup(pool, blade_subscription_channel_get(bsub));
}
ks_hash_read_unlock(bsmgr->subscriptions);
if (!unsubbed) {
- blade_subscriptionmgr_subscriber_remove(bsmgr, NULL, protocol, realm, channel, target);
+ blade_subscriptionmgr_subscriber_remove(bsmgr, NULL, protocol, channel, target);
ks_pool_free(&protocol);
- ks_pool_free(&realm);
ks_pool_free(&channel);
}
}
}
-KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t *bsmgr, blade_rpcbroadcast_command_t command, const char *excluded_nodeid, const char *protocol, const char *realm, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data)
+KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t *bsmgr, blade_rpcbroadcast_command_t command, const char *excluded_nodeid, const char *protocol, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data)
{
ks_pool_t *pool = NULL;
const char *bsub_key = NULL;
@@ -358,16 +351,16 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t
ks_assert(bsmgr);
ks_assert(protocol);
- ks_assert(realm);
pool = ks_pool_get(bsmgr);
switch (command) {
case BLADE_RPCBROADCAST_COMMAND_EVENT:
+ ks_assert(channel);
ks_assert(event);
case BLADE_RPCBROADCAST_COMMAND_CHANNEL_REMOVE:
ks_assert(channel);
- bsub_key = ks_psprintf(pool, "%s@%s/%s", protocol, realm, channel);
+ bsub_key = ks_psprintf(pool, "%s:%s", protocol, channel);
ks_hash_read_lock(bsmgr->subscriptions);
@@ -386,7 +379,7 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t
if (excluded_nodeid && !ks_safe_strcasecmp(excluded_nodeid, (const char *)key)) continue;
// @todo broadcast producer is also a local subscriber... requires special consideration with no session to request through
- if (blade_upstreammgr_localid_compare(blade_handle_upstreammgr_get(bsmgr->handle), (const char *)key)) continue;
+ if (blade_routemgr_local_check(blade_handle_routemgr_get(bsmgr->handle), (const char *)key)) continue;
bs = blade_routemgr_route_lookup(blade_handle_routemgr_get(bsmgr->handle), (const char *)key);
if (bs) {
@@ -404,7 +397,7 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t
ks_hash_read_unlock(bsmgr->subscriptions);
break;
case BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE:
- bsub_key = ks_psprintf(pool, "%s@%s", protocol, realm);
+ bsub_key = ks_pstrdup(pool, protocol);
ks_hash_read_lock(bsmgr->subscriptions);
@@ -430,7 +423,7 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t
if (excluded_nodeid && !ks_safe_strcasecmp(excluded_nodeid, (const char *)key2)) continue;
// @todo broadcast producer is also a local subscriber... requires special consideration with no session to request through
- if (blade_upstreammgr_localid_compare(blade_handle_upstreammgr_get(bsmgr->handle), (const char *)key2)) continue;
+ if (blade_routemgr_local_check(blade_handle_routemgr_get(bsmgr->handle), (const char *)key2)) continue;
bs = blade_routemgr_route_lookup(blade_handle_routemgr_get(bsmgr->handle), (const char *)key2);
if (bs) {
@@ -451,7 +444,7 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t
}
- bs = blade_upstreammgr_session_get(blade_handle_upstreammgr_get(bsmgr->handle));
+ bs = blade_routemgr_upstream_lookup(blade_handle_routemgr_get(bsmgr->handle));
if (bs) {
if (!excluded_nodeid || ks_safe_strcasecmp(blade_session_id_get(bs), excluded_nodeid)) {
if (!routers) ks_hash_create(&routers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_NOLOCK | KS_HASH_FLAG_DUP_CHECK, pool);
@@ -467,7 +460,7 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t
ks_hash_this(it, (const void **)&key, NULL, &value);
- blade_subscriptionmgr_subscription_remove(bsmgr, protocol, realm, (const char *)key);
+ blade_subscriptionmgr_subscription_remove(bsmgr, protocol, (const char *)key);
}
ks_hash_destroy(&channels);
}
@@ -484,12 +477,11 @@ KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t
blade_rpc_request_raw_create(pool, &req, &req_params, NULL, "blade.broadcast");
cJSON_AddNumberToObject(req_params, "command", command);
cJSON_AddStringToObject(req_params, "protocol", protocol);
- cJSON_AddStringToObject(req_params, "realm", realm);
if (channel) cJSON_AddStringToObject(req_params, "channel", channel);
if (event) cJSON_AddStringToObject(req_params, "event", event);
if (params) cJSON_AddItemToObject(req_params, "params", cJSON_Duplicate(params, 1));
- ks_log(KS_LOG_DEBUG, "Broadcasting: %s through %s\n", bsub_key, blade_session_id_get(bs));
+ ks_log(KS_LOG_DEBUG, "Broadcasting: protocol %s, channel %s through %s\n", protocol, channel, blade_session_id_get(bs));
blade_session_send(bs, req, callback, data);
diff --git a/libs/libblade/src/blade_transport_wss.c b/libs/libblade/src/blade_transport_wss.c
index db55ca4e44..ea123f4a0e 100644
--- a/libs/libblade/src/blade_transport_wss.c
+++ b/libs/libblade/src/blade_transport_wss.c
@@ -609,7 +609,7 @@ ks_status_t blade_transport_wss_onconnect(blade_connection_t **bcP, blade_transp
int family = AF_INET;
const char *ip = NULL;
const char *portstr = NULL;
- ks_port_t port = 1234;
+ ks_port_t port = 2100;
blade_transport_wss_link_t *btwssl = NULL;
blade_connection_t *bc = NULL;
@@ -621,19 +621,18 @@ ks_status_t blade_transport_wss_onconnect(blade_connection_t **bcP, blade_transp
*bcP = NULL;
- ks_log(KS_LOG_DEBUG, "Connect Callback: %s\n", blade_identity_uri(target));
+ ks_log(KS_LOG_DEBUG, "Connect Callback: %s\n", blade_identity_uri_get(target));
// @todo completely rework all of this once more is known about connecting when an identity has no explicit transport details but this transport
// has been choosen anyway
- ip = blade_identity_parameter_get(target, "host");
- portstr = blade_identity_parameter_get(target, "port");
+ ip = blade_identity_host_get(target);
+ portstr = blade_identity_port_get(target);
if (!ip) {
- // @todo: temporary, this should fall back on DNS SRV or whatever else can turn "a@b.com" into an ip (and port?) to connect to
- // also need to deal with hostname lookup, so identities with wss transport need to have a host parameter that is an IP for the moment
ks_log(KS_LOG_DEBUG, "No host provided\n");
ret = KS_STATUS_FAIL;
goto done;
}
+ // @todo: this should detect IP's and fall back on DNS and/or SRV for hostname lookup, for the moment hosts must be IP's
// @todo wrap this code to get address family from string IP between IPV4 and IPV6, and put it in libks somewhere
{
@@ -830,12 +829,10 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
//cJSON *error = NULL;
blade_session_t *bs = NULL;
blade_handle_t *bh = NULL;
- ks_pool_t *pool = NULL;
const char *jsonrpc = NULL;
const char *id = NULL;
const char *method = NULL;
const char *nodeid = NULL;
- const char *master_nodeid = NULL;
ks_time_t timeout;
ks_assert(bc);
@@ -951,9 +948,9 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
// from having long running write locks when a session cleans up
blade_session_route_add(bs, nodeid);
// This is the main routing entry to make an identity routable through a session when a message is received for a given identity in this table, these allow to efficiently determine which session
- // a message should pass through when it does not match the local node id from blade_upstreammgr_t, and must be matched with a call to blade_session_route_add() for cleanup, additionally when
- // a "blade.register" is received the identity it carries affects these routes along with the sessionid of the downstream session it came through, and "blade.register" would also
- // result in the new identities being added as routes however new entire wildcard subrealm registration would require a special process for matching any identities from those subrealms
+ // a message should pass through when it does not match the local node id from blade_routemgr_t, and must be matched with a call to blade_session_route_add() for cleanup, additionally when
+ // a "blade.route" is received the identity it carries affects these routes along with the sessionid of the downstream session it came through, and "blade.route" would also
+ // result in the new identities being added as routes however federation registration would require a special process to maintain proper routing
blade_routemgr_route_add(blade_handle_routemgr_get(bh), nodeid, nodeid);
}
@@ -962,18 +959,12 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
cJSON_AddStringToObject(json_result, "nodeid", nodeid);
- // @todo process automatic identity registration from remote SANS entries
-
- pool = ks_pool_get(bh);
- blade_upstreammgr_masterid_copy(blade_handle_upstreammgr_get(bh), pool, &master_nodeid);
- if (!master_nodeid) {
+ if (!blade_routemgr_master_pack(blade_handle_routemgr_get(bh), json_result, "master-nodeid")) {
ks_log(KS_LOG_DEBUG, "Master nodeid unavailable\n");
blade_transport_wss_rpc_error_send(bc, id, -32602, "Master nodeid unavailable");
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
goto done;
}
- cJSON_AddStringToObject(json_result, "master-nodeid", master_nodeid);
- ks_pool_free(&master_nodeid);
// This starts the final process for associating the connection to the session, including for reconnecting to an existing session, this simply
// associates the session to this connection, upon return the remainder of the association for the session to the connection is handled along
@@ -995,7 +986,6 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
if (json_req) cJSON_Delete(json_req);
if (json_res) cJSON_Delete(json_res);
-
return ret;
}
@@ -1103,8 +1093,6 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_outbound(blade
goto done;
}
- // @todo parse and process automatic identity registration coming from local SANS entries, but given back in the connect response in case there are any errors (IE: missing realm or duplicate identity)
-
master_nodeid = cJSON_GetObjectCstr(json_result, "master-nodeid");
if (!master_nodeid) {
ks_log(KS_LOG_DEBUG, "Received message 'result' is missing 'master-nodeid'\n");
@@ -1137,7 +1125,7 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_outbound(blade
// This is an outbound connection, thus it is always creating an upstream session, defined by the sessionid matching the local_nodeid in the handle
- if (blade_upstreammgr_localid_set(blade_handle_upstreammgr_get(bh), nodeid) != KS_STATUS_SUCCESS) {
+ if (blade_routemgr_local_set(blade_handle_routemgr_get(bh), nodeid) != KS_STATUS_SUCCESS) {
ks_log(KS_LOG_DEBUG, "Session (%s) abandoned, upstream already available\n", blade_session_id_get(bs));
blade_session_read_unlock(bs);
blade_session_hangup(bs);
@@ -1149,7 +1137,7 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_outbound(blade
blade_sessionmgr_session_add(blade_handle_sessionmgr_get(bh), bs);
- blade_upstreammgr_masterid_set(blade_handle_upstreammgr_get(bh), master_nodeid);
+ blade_routemgr_master_set(blade_handle_routemgr_get(bh), master_nodeid);
}
blade_connection_session_set(bc, blade_session_id_get(bs));
diff --git a/libs/libblade/src/blade_upstreammgr.c b/libs/libblade/src/blade_upstreammgr.c
deleted file mode 100644
index bcdee57834..0000000000
--- a/libs/libblade/src/blade_upstreammgr.c
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (c) 2017, Shane Bryldt
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "blade.h"
-
-struct blade_upstreammgr_s {
- blade_handle_t *handle;
-
- // local node id, can be used to get the upstream session, provided by upstream "blade.connect" response
- const char *localid;
- ks_rwl_t *localid_rwl;
-
- // master node id, provided by upstream "blade.connect" response
- const char *masterid;
- ks_rwl_t *masterid_rwl;
-};
-
-
-static void blade_upstreammgr_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
-{
- //blade_upstreammgr_t *bumgr = (blade_upstreammgr_t *)ptr;
-
- //ks_assert(brmgr);
-
- switch (action) {
- case KS_MPCL_ANNOUNCE:
- break;
- case KS_MPCL_TEARDOWN:
- break;
- case KS_MPCL_DESTROY:
- break;
- }
-}
-
-KS_DECLARE(ks_status_t) blade_upstreammgr_create(blade_upstreammgr_t **bumgrP, blade_handle_t *bh)
-{
- ks_pool_t *pool = NULL;
- blade_upstreammgr_t *bumgr = NULL;
-
- ks_assert(bumgrP);
-
- ks_pool_open(&pool);
- ks_assert(pool);
-
- bumgr = ks_pool_alloc(pool, sizeof(blade_upstreammgr_t));
- bumgr->handle = bh;
-
- //ks_hash_create(&bumgr->routes, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY | KS_HASH_FLAG_FREE_VALUE, pool);
- //ks_assert(bumgr->routes);
- ks_rwl_create(&bumgr->localid_rwl, pool);
- ks_assert(bumgr->localid_rwl);
-
- ks_rwl_create(&bumgr->masterid_rwl, pool);
- ks_assert(bumgr->masterid_rwl);
-
- ks_pool_set_cleanup(bumgr, NULL, blade_upstreammgr_cleanup);
-
- *bumgrP = bumgr;
-
- return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_upstreammgr_destroy(blade_upstreammgr_t **bumgrP)
-{
- blade_upstreammgr_t *bumgr = NULL;
- ks_pool_t *pool;
-
- ks_assert(bumgrP);
- ks_assert(*bumgrP);
-
- bumgr = *bumgrP;
- *bumgrP = NULL;
-
- pool = ks_pool_get(bumgr);
-
- ks_pool_close(&pool);
-
- return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(blade_handle_t *) blade_upstreammgr_handle_get(blade_upstreammgr_t *bumgr)
-{
- ks_assert(bumgr);
- return bumgr->handle;
-}
-
-KS_DECLARE(ks_status_t) blade_upstreammgr_localid_set(blade_upstreammgr_t *bumgr, const char *id)
-{
- ks_status_t ret = KS_STATUS_SUCCESS;
-
- ks_assert(bumgr);
-
- ks_rwl_write_lock(bumgr->localid_rwl);
- if (bumgr->localid && id) {
- ret = KS_STATUS_NOT_ALLOWED;
- goto done;
- }
- if (!bumgr->localid && !id) {
- ret = KS_STATUS_DISCONNECTED;
- goto done;
- }
-
- if (bumgr->localid) ks_pool_free(&bumgr->localid);
- if (id) bumgr->localid = ks_pstrdup(ks_pool_get(bumgr), id);
-
- ks_log(KS_LOG_DEBUG, "LocalID: %s\n", id);
-
-done:
- ks_rwl_write_unlock(bumgr->localid_rwl);
- return ret;
-}
-
-KS_DECLARE(ks_bool_t) blade_upstreammgr_localid_compare(blade_upstreammgr_t *bumgr, const char *id)
-{
- ks_bool_t ret = KS_FALSE;
-
- ks_assert(bumgr);
- ks_assert(id);
-
- ks_rwl_read_lock(bumgr->localid_rwl);
- ret = ks_safe_strcasecmp(bumgr->localid, id) == 0;
- ks_rwl_read_unlock(bumgr->localid_rwl);
-
- return ret;
-}
-
-KS_DECLARE(ks_status_t) blade_upstreammgr_localid_copy(blade_upstreammgr_t *bumgr, ks_pool_t *pool, const char **id)
-{
- ks_assert(bumgr);
- ks_assert(pool);
- ks_assert(id);
-
- *id = NULL;
-
- ks_rwl_read_lock(bumgr->localid_rwl);
- if (bumgr->localid) *id = ks_pstrdup(pool, bumgr->localid);
- ks_rwl_read_unlock(bumgr->localid_rwl);
-
- return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_bool_t) blade_upstreammgr_session_established(blade_upstreammgr_t *bumgr)
-{
- ks_bool_t ret = KS_FALSE;
-
- ks_assert(bumgr);
-
- ks_rwl_read_lock(bumgr->localid_rwl);
- ret = bumgr->localid != NULL;
- ks_rwl_read_unlock(bumgr->localid_rwl);
-
- return ret;
-}
-
-KS_DECLARE(blade_session_t *) blade_upstreammgr_session_get(blade_upstreammgr_t *bumgr)
-{
- blade_session_t *bs = NULL;
-
- ks_assert(bumgr);
-
- ks_rwl_read_lock(bumgr->localid_rwl);
- if (bumgr->localid) bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bumgr->handle), bumgr->localid);
- ks_rwl_read_unlock(bumgr->localid_rwl);
-
- return bs;
-}
-
-KS_DECLARE(ks_status_t) blade_upstreammgr_masterid_set(blade_upstreammgr_t *bumgr, const char *id)
-{
- ks_status_t ret = KS_STATUS_SUCCESS;
-
- ks_assert(bumgr);
-
- ks_rwl_write_lock(bumgr->masterid_rwl);
- if (bumgr->masterid) ks_pool_free(&bumgr->masterid);
- if (id) bumgr->masterid = ks_pstrdup(ks_pool_get(bumgr), id);
-
- ks_log(KS_LOG_DEBUG, "MasterID: %s\n", id);
-
- ks_rwl_write_unlock(bumgr->masterid_rwl);
- return ret;
-}
-
-KS_DECLARE(ks_bool_t) blade_upstreammgr_masterid_compare(blade_upstreammgr_t *bumgr, const char *id)
-{
- ks_bool_t ret = KS_FALSE;
-
- ks_assert(bumgr);
- ks_assert(id);
-
- ks_rwl_read_lock(bumgr->masterid_rwl);
- ret = ks_safe_strcasecmp(bumgr->masterid, id) == 0;
- ks_rwl_read_unlock(bumgr->masterid_rwl);
-
- return ret;
-}
-
-KS_DECLARE(ks_status_t) blade_upstreammgr_masterid_copy(blade_upstreammgr_t *bumgr, ks_pool_t *pool, const char **id)
-{
- ks_assert(bumgr);
- ks_assert(pool);
- ks_assert(id);
-
- *id = NULL;
-
- ks_rwl_read_lock(bumgr->masterid_rwl);
- if (bumgr->masterid) *id = ks_pstrdup(pool, bumgr->masterid);
- ks_rwl_read_unlock(bumgr->masterid_rwl);
-
- return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_bool_t) blade_upstreammgr_masterlocal(blade_upstreammgr_t *bumgr)
-{
- ks_bool_t ret = KS_FALSE;
-
- ks_assert(bumgr);
-
- ks_rwl_read_lock(bumgr->masterid_rwl);
- ks_rwl_read_lock(bumgr->localid_rwl);
- ret = bumgr->masterid && bumgr->localid && !ks_safe_strcasecmp(bumgr->masterid, bumgr->localid);
- ks_rwl_read_unlock(bumgr->localid_rwl);
- ks_rwl_read_unlock(bumgr->masterid_rwl);
-
- return ret;
-}
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
- */
diff --git a/libs/libblade/src/include/blade.h b/libs/libblade/src/include/blade.h
index eb5d7d222b..b47ace6153 100644
--- a/libs/libblade/src/include/blade.h
+++ b/libs/libblade/src/include/blade.h
@@ -44,7 +44,6 @@
#include "blade_rpc.h"
#include "blade_connection.h"
#include "blade_session.h"
-#include "blade_realm.h"
#include "blade_protocol.h"
#include "blade_channel.h"
#include "blade_subscription.h"
@@ -54,7 +53,6 @@
#include "blade_rpcmgr.h"
#include "blade_routemgr.h"
#include "blade_subscriptionmgr.h"
-#include "blade_upstreammgr.h"
#include "blade_mastermgr.h"
#include "blade_connectionmgr.h"
#include "blade_sessionmgr.h"
diff --git a/libs/libblade/src/include/blade_channel.h b/libs/libblade/src/include/blade_channel.h
index 64885f6dd5..660748dd36 100644
--- a/libs/libblade/src/include/blade_channel.h
+++ b/libs/libblade/src/include/blade_channel.h
@@ -36,9 +36,10 @@
#include
KS_BEGIN_EXTERN_C
-KS_DECLARE(ks_status_t) blade_channel_create(blade_channel_t **bcP, ks_pool_t *pool, const char *name);
+KS_DECLARE(ks_status_t) blade_channel_create(blade_channel_t **bcP, ks_pool_t *pool, const char *name, blade_channel_flags_t flags);
KS_DECLARE(ks_status_t) blade_channel_destroy(blade_channel_t **bcP);
KS_DECLARE(const char *) blade_channel_name_get(blade_channel_t *bc);
+KS_DECLARE(blade_channel_flags_t) blade_channel_flags_get(blade_channel_t *bc);
KS_DECLARE(ks_status_t) blade_channel_read_lock(blade_channel_t *bc);
KS_DECLARE(ks_status_t) blade_channel_read_unlock(blade_channel_t *bc);
KS_DECLARE(ks_status_t) blade_channel_write_lock(blade_channel_t *bc);
diff --git a/libs/libblade/src/include/blade_identity.h b/libs/libblade/src/include/blade_identity.h
index 8d8329459e..bdef1d203e 100644
--- a/libs/libblade/src/include/blade_identity.h
+++ b/libs/libblade/src/include/blade_identity.h
@@ -39,8 +39,14 @@ KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_identity_create(blade_identity_t **biP, ks_pool_t *pool);
KS_DECLARE(ks_status_t) blade_identity_destroy(blade_identity_t **biP);
KS_DECLARE(ks_status_t) blade_identity_parse(blade_identity_t *bi, const char *uri);
-KS_DECLARE(const char *) blade_identity_uri(blade_identity_t *bi);
-KS_DECLARE(const char *) blade_identity_parameter_get(blade_identity_t *bi, const char *key);
+KS_DECLARE(const char *) blade_identity_uri_get(blade_identity_t *bi);
+KS_DECLARE(const char *) blade_identity_scheme_get(blade_identity_t *bi);
+KS_DECLARE(const char *) blade_identity_user_get(blade_identity_t *bi);
+KS_DECLARE(const char *) blade_identity_host_get(blade_identity_t *bi);
+KS_DECLARE(const char *) blade_identity_port_get(blade_identity_t *bi);
+KS_DECLARE(ks_port_t) blade_identity_portnum_get(blade_identity_t *bi);
+KS_DECLARE(const char *) blade_identity_path_get(blade_identity_t *bi);
+KS_DECLARE(const char *) blade_identity_parameter_lookup(blade_identity_t *bi, const char *key);
KS_END_EXTERN_C
#endif
diff --git a/libs/libblade/src/include/blade_mastermgr.h b/libs/libblade/src/include/blade_mastermgr.h
index 12a97d220e..11242aee9a 100644
--- a/libs/libblade/src/include/blade_mastermgr.h
+++ b/libs/libblade/src/include/blade_mastermgr.h
@@ -42,15 +42,13 @@ KS_DECLARE(ks_status_t) blade_mastermgr_startup(blade_mastermgr_t *bmmgr, config
KS_DECLARE(ks_status_t) blade_mastermgr_shutdown(blade_mastermgr_t *bmmgr);
KS_DECLARE(blade_handle_t *) blade_mastermgr_handle_get(blade_mastermgr_t *bmmgr);
KS_DECLARE(ks_status_t) blade_mastermgr_purge(blade_mastermgr_t *bmmgr, const char *nodeid);
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_add(blade_mastermgr_t *bmmgr, blade_realm_t *realm);
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_remove(blade_mastermgr_t *bmmgr, const char *realm);
-KS_DECLARE(blade_protocol_t *) blade_mastermgr_realm_protocol_lookup(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, ks_bool_t writelocked);
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_controller_add(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *controller);
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_controller_remove(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *controller);
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_channel_add(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *channel);
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_channel_remove(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *channel);
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_channel_authorize(blade_mastermgr_t *bmmgr, ks_bool_t remove, const char *realm, const char *protocol, const char *channel, const char *controller, const char *target);
-KS_DECLARE(ks_bool_t) blade_mastermgr_realm_protocol_channel_authorization_verify(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *channel, const char *target);
+KS_DECLARE(blade_protocol_t *) blade_mastermgr_protocol_lookup(blade_mastermgr_t *bmmgr, const char *protocol, ks_bool_t writelocked);
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_controller_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *controller);
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_controller_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *controller);
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel, blade_channel_flags_t flags);
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel);
+KS_DECLARE(ks_status_t) blade_mastermgr_protocol_channel_authorize(blade_mastermgr_t *bmmgr, ks_bool_t remove, const char *protocol, const char *channel, const char *controller, const char *target);
+KS_DECLARE(ks_bool_t) blade_mastermgr_protocol_channel_authorization_verify(blade_mastermgr_t *bmmgr, const char *protocol, const char *channel, const char *target);
KS_END_EXTERN_C
#endif
diff --git a/libs/libblade/src/include/blade_protocol.h b/libs/libblade/src/include/blade_protocol.h
index cdbf74ce53..bb59a1da63 100644
--- a/libs/libblade/src/include/blade_protocol.h
+++ b/libs/libblade/src/include/blade_protocol.h
@@ -36,9 +36,8 @@
#include
KS_BEGIN_EXTERN_C
-KS_DECLARE(ks_status_t) blade_protocol_create(blade_protocol_t **bpP, ks_pool_t *pool, blade_realm_t *realm, const char *name);
+KS_DECLARE(ks_status_t) blade_protocol_create(blade_protocol_t **bpP, ks_pool_t *pool, const char *name);
KS_DECLARE(ks_status_t) blade_protocol_destroy(blade_protocol_t **bpP);
-KS_DECLARE(blade_realm_t *) blade_protocol_realm_get(blade_protocol_t *bp);
KS_DECLARE(const char *) blade_protocol_name_get(blade_protocol_t *bp);
KS_DECLARE(ks_status_t) blade_protocol_read_lock(blade_protocol_t *bp);
KS_DECLARE(ks_status_t) blade_protocol_read_unlock(blade_protocol_t *bp);
diff --git a/libs/libblade/src/include/blade_realm.h b/libs/libblade/src/include/blade_realm.h
deleted file mode 100644
index 1e70f5c06c..0000000000
--- a/libs/libblade/src/include/blade_realm.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2017, Shane Bryldt
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _BLADE_REALM_H_
-#define _BLADE_REALM_H_
-#include
-
-KS_BEGIN_EXTERN_C
-KS_DECLARE(ks_status_t) blade_realm_create(blade_realm_t **brP, ks_pool_t *pool, const char *name);
-KS_DECLARE(ks_status_t) blade_realm_destroy(blade_realm_t **brP);
-KS_DECLARE(const char *) blade_realm_name_get(blade_realm_t *br);
-KS_DECLARE(ks_status_t) blade_realm_read_lock(blade_realm_t *br);
-KS_DECLARE(ks_status_t) blade_realm_read_unlock(blade_realm_t *br);
-KS_DECLARE(ks_status_t) blade_realm_write_lock(blade_realm_t *br);
-KS_DECLARE(ks_status_t) blade_realm_write_unlock(blade_realm_t *br);
-KS_DECLARE(ks_hash_iterator_t *) blade_realm_protocols_iterator(blade_realm_t *br, ks_locked_t locked);
-KS_DECLARE(blade_protocol_t *) blade_realm_protocol_lookup(blade_realm_t *br, const char *protocol, ks_bool_t writelocked);
-KS_DECLARE(ks_status_t) blade_realm_protocol_add(blade_realm_t *br, blade_protocol_t *protocol);
-KS_DECLARE(ks_status_t) blade_realm_protocol_remove(blade_realm_t *br, const char *protocol);
-KS_END_EXTERN_C
-
-#endif
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
- */
diff --git a/libs/libblade/src/include/blade_routemgr.h b/libs/libblade/src/include/blade_routemgr.h
index 9f7830a020..c75426c183 100644
--- a/libs/libblade/src/include/blade_routemgr.h
+++ b/libs/libblade/src/include/blade_routemgr.h
@@ -39,9 +39,20 @@ KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_routemgr_create(blade_routemgr_t **brmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_routemgr_destroy(blade_routemgr_t **brmgrP);
KS_DECLARE(blade_handle_t *) blade_routemgr_handle_get(blade_routemgr_t *brmgr);
+KS_DECLARE(ks_status_t) blade_routemgr_local_set(blade_routemgr_t *brmgr, const char *nodeid);
+KS_DECLARE(ks_bool_t) blade_routemgr_local_check(blade_routemgr_t *brmgr, const char *target);
+KS_DECLARE(ks_bool_t) blade_routemgr_local_copy(blade_routemgr_t *brmgr, const char **nodeid);
+KS_DECLARE(ks_bool_t) blade_routemgr_local_pack(blade_routemgr_t *brmgr, cJSON *json, const char *key);
+KS_DECLARE(blade_session_t *) blade_routemgr_upstream_lookup(blade_routemgr_t *brmgr);
+KS_DECLARE(ks_status_t) blade_routemgr_master_set(blade_routemgr_t *brmgr, const char *nodeid);
+KS_DECLARE(ks_bool_t) blade_routemgr_master_check(blade_routemgr_t *brmgr, const char *target);
+KS_DECLARE(ks_bool_t) blade_routemgr_master_pack(blade_routemgr_t *brmgr, cJSON *json, const char *key);
+KS_DECLARE(ks_bool_t) blade_routemgr_master_local(blade_routemgr_t *brmgr);
KS_DECLARE(blade_session_t *) blade_routemgr_route_lookup(blade_routemgr_t *brmgr, const char *target);
KS_DECLARE(ks_status_t) blade_routemgr_route_add(blade_routemgr_t *brmgr, const char *target, const char *router);
KS_DECLARE(ks_status_t) blade_routemgr_route_remove(blade_routemgr_t *brmgr, const char *target);
+KS_DECLARE(ks_status_t) blade_routemgr_identity_add(blade_routemgr_t *brmgr, blade_identity_t *identity, const char *target);
+KS_DECLARE(ks_status_t) blade_routemgr_identity_remove(blade_routemgr_t *brmgr, blade_identity_t *identity, const char *target);
KS_END_EXTERN_C
#endif
diff --git a/libs/libblade/src/include/blade_rpc.h b/libs/libblade/src/include/blade_rpc.h
index a966088af4..69e83344b2 100644
--- a/libs/libblade/src/include/blade_rpc.h
+++ b/libs/libblade/src/include/blade_rpc.h
@@ -36,12 +36,11 @@
#include
KS_BEGIN_EXTERN_C
-KS_DECLARE(ks_status_t) blade_rpc_create(blade_rpc_t **brpcP, blade_handle_t *bh, const char *method, const char *protocol, const char *realm, blade_rpc_request_callback_t callback, void *data);
+KS_DECLARE(ks_status_t) blade_rpc_create(blade_rpc_t **brpcP, blade_handle_t *bh, const char *method, const char *protocol, blade_rpc_request_callback_t callback, void *data);
KS_DECLARE(ks_status_t) blade_rpc_destroy(blade_rpc_t **brpcP);
KS_DECLARE(blade_handle_t *) blade_rpc_handle_get(blade_rpc_t *brpc);
KS_DECLARE(const char *) blade_rpc_method_get(blade_rpc_t *brpc);
KS_DECLARE(const char *) blade_rpc_protocol_get(blade_rpc_t *brpc);
-KS_DECLARE(const char *) blade_rpc_realm_get(blade_rpc_t *brpc);
KS_DECLARE(blade_rpc_request_callback_t) blade_rpc_callback_get(blade_rpc_t *brpc);
KS_DECLARE(void *) blade_rpc_data_get(blade_rpc_t *brpc);
diff --git a/libs/libblade/src/include/blade_rpcmgr.h b/libs/libblade/src/include/blade_rpcmgr.h
index b45fb6439f..2d93189812 100644
--- a/libs/libblade/src/include/blade_rpcmgr.h
+++ b/libs/libblade/src/include/blade_rpcmgr.h
@@ -42,7 +42,7 @@ KS_DECLARE(blade_handle_t *) blade_rpcmgr_handle_get(blade_rpcmgr_t *brpcmgr);
KS_DECLARE(blade_rpc_t *) blade_rpcmgr_corerpc_lookup(blade_rpcmgr_t *brpcmgr, const char *method);
KS_DECLARE(ks_status_t) blade_rpcmgr_corerpc_add(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc);
KS_DECLARE(ks_status_t) blade_rpcmgr_corerpc_remove(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc);
-KS_DECLARE(blade_rpc_t *) blade_rpcmgr_protocolrpc_lookup(blade_rpcmgr_t *brpcmgr, const char *method, const char *protocol, const char *realm);
+KS_DECLARE(blade_rpc_t *) blade_rpcmgr_protocolrpc_lookup(blade_rpcmgr_t *brpcmgr, const char *method, const char *protocol);
KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_add(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc);
KS_DECLARE(ks_status_t) blade_rpcmgr_protocolrpc_remove(blade_rpcmgr_t *brpcmgr, blade_rpc_t *brpc);
KS_DECLARE(blade_rpc_request_t *) blade_rpcmgr_request_lookup(blade_rpcmgr_t *brpcmgr, const char *id);
diff --git a/libs/libblade/src/include/blade_session.h b/libs/libblade/src/include/blade_session.h
index b84ac257ad..4bdbe8a85c 100644
--- a/libs/libblade/src/include/blade_session.h
+++ b/libs/libblade/src/include/blade_session.h
@@ -43,9 +43,6 @@ KS_DECLARE(ks_status_t) blade_session_shutdown(blade_session_t *bs);
KS_DECLARE(blade_handle_t *) blade_session_handle_get(blade_session_t *bs);
KS_DECLARE(const char *) blade_session_id_get(blade_session_t *bs);
KS_DECLARE(blade_session_state_t) blade_session_state_get(blade_session_t *bs);
-KS_DECLARE(ks_status_t) blade_session_realm_add(blade_session_t *bs, const char *realm);
-KS_DECLARE(ks_status_t) blade_session_realm_remove(blade_session_t *bs, const char *realm);
-KS_DECLARE(ks_hash_t *) blade_session_realms_get(blade_session_t *bs);
KS_DECLARE(ks_status_t) blade_session_route_add(blade_session_t *bs, const char *nodeid);
KS_DECLARE(ks_status_t) blade_session_route_remove(blade_session_t *bs, const char *nodeid);
KS_DECLARE(cJSON *) blade_session_properties_get(blade_session_t *bs);
diff --git a/libs/libblade/src/include/blade_stack.h b/libs/libblade/src/include/blade_stack.h
index 4e9c03438e..4a8df5c835 100644
--- a/libs/libblade/src/include/blade_stack.h
+++ b/libs/libblade/src/include/blade_stack.h
@@ -51,33 +51,33 @@ KS_DECLARE(blade_transportmgr_t *) blade_handle_transportmgr_get(blade_handle_t
KS_DECLARE(blade_rpcmgr_t *) blade_handle_rpcmgr_get(blade_handle_t *bh);
KS_DECLARE(blade_routemgr_t *) blade_handle_routemgr_get(blade_handle_t *bh);
KS_DECLARE(blade_subscriptionmgr_t *) blade_handle_subscriptionmgr_get(blade_handle_t *bh);
-KS_DECLARE(blade_upstreammgr_t *) blade_handle_upstreammgr_get(blade_handle_t *bh);
KS_DECLARE(blade_mastermgr_t *) blade_handle_mastermgr_get(blade_handle_t *bh);
KS_DECLARE(blade_connectionmgr_t *) blade_handle_connectionmgr_get(blade_handle_t *bh);
KS_DECLARE(blade_sessionmgr_t *) blade_handle_sessionmgr_get(blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connection_t **bcP, blade_identity_t *target, const char *session_id);
-KS_DECLARE(ks_status_t) blade_handle_rpcregister(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, blade_rpc_response_callback_t callback, void *data);
+KS_DECLARE(ks_status_t) blade_handle_rpcroute(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, blade_rpc_response_callback_t callback, void *data);
-KS_DECLARE(ks_status_t) blade_handle_rpcpublish(blade_handle_t *bh, blade_rpcpublish_command_t command, const char *protocol, const char *realm, cJSON *channels, blade_rpc_response_callback_t callback, void *data);
+KS_DECLARE(ks_status_t) blade_handle_rpcregister(blade_handle_t *bh, const char *identity, blade_rpc_response_callback_t callback, void *data);
-KS_DECLARE(ks_status_t) blade_handle_rpcauthorize(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, const char *protocol, const char *realm, cJSON *channels, blade_rpc_response_callback_t callback, void *data);
+KS_DECLARE(ks_status_t) blade_handle_rpcpublish(blade_handle_t *bh, blade_rpcpublish_command_t command, const char *protocol, cJSON *channels, blade_rpc_response_callback_t callback, void *data);
-KS_DECLARE(ks_status_t) blade_handle_rpclocate(blade_handle_t *bh, const char *protocol, const char *realm, blade_rpc_response_callback_t callback, void *data);
+KS_DECLARE(ks_status_t) blade_handle_rpcauthorize(blade_handle_t *bh, const char *nodeid, ks_bool_t remove, const char *protocol, cJSON *channels, blade_rpc_response_callback_t callback, void *data);
-KS_DECLARE(ks_status_t) blade_handle_rpcexecute(blade_handle_t *bh, const char *nodeid, const char *method, const char *protocol, const char *realm, cJSON *params, blade_rpc_response_callback_t callback, void *data);
+KS_DECLARE(ks_status_t) blade_handle_rpclocate(blade_handle_t *bh, const char *protocol, blade_rpc_response_callback_t callback, void *data);
+
+KS_DECLARE(ks_status_t) blade_handle_rpcexecute(blade_handle_t *bh, const char *nodeid, const char *method, const char *protocol, cJSON *params, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(const char *) blade_rpcexecute_request_requester_nodeid_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpcexecute_request_responder_nodeid_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(cJSON *) blade_rpcexecute_request_params_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(cJSON *) blade_rpcexecute_response_result_get(blade_rpc_response_t *brpcres);
KS_DECLARE(void) blade_rpcexecute_response_send(blade_rpc_request_t *brpcreq, cJSON *result);
-KS_DECLARE(ks_status_t) blade_handle_rpcsubscribe(blade_handle_t *bh, blade_rpcsubscribe_command_t command, const char *protocol, const char *realm, cJSON *channels, blade_rpc_response_callback_t callback, void *data, blade_rpc_request_callback_t channel_callback, void *channel_data);
+KS_DECLARE(ks_status_t) blade_handle_rpcsubscribe(blade_handle_t *bh, blade_rpcsubscribe_command_t command, const char *protocol, cJSON *channels, blade_rpc_response_callback_t callback, void *data, blade_rpc_request_callback_t channel_callback, void *channel_data);
-KS_DECLARE(ks_status_t) blade_handle_rpcbroadcast(blade_handle_t *bh, const char *protocol, const char *realm, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data);
+KS_DECLARE(ks_status_t) blade_handle_rpcbroadcast(blade_handle_t *bh, const char *protocol, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data);
KS_DECLARE(cJSON *) blade_rpcbroadcast_request_params_get(blade_rpc_request_t *brpcreq);
-KS_DECLARE(const char *) blade_rpcbroadcast_request_realm_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpcbroadcast_request_protocol_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpcbroadcast_request_channel_get(blade_rpc_request_t *brpcreq);
KS_DECLARE(const char *) blade_rpcbroadcast_request_event_get(blade_rpc_request_t *brpcreq);
diff --git a/libs/libblade/src/include/blade_subscription.h b/libs/libblade/src/include/blade_subscription.h
index 96052a744e..5c591941bd 100644
--- a/libs/libblade/src/include/blade_subscription.h
+++ b/libs/libblade/src/include/blade_subscription.h
@@ -36,10 +36,9 @@
#include
KS_BEGIN_EXTERN_C
-KS_DECLARE(ks_status_t) blade_subscription_create(blade_subscription_t **bsubP, ks_pool_t *pool, const char *protocol, const char *realm, const char *channel);
+KS_DECLARE(ks_status_t) blade_subscription_create(blade_subscription_t **bsubP, ks_pool_t *pool, const char *protocol, const char *channel);
KS_DECLARE(ks_status_t) blade_subscription_destroy(blade_subscription_t **bsubP);
KS_DECLARE(const char *) blade_subscription_protocol_get(blade_subscription_t *bsub);
-KS_DECLARE(const char *) blade_subscription_realm_get(blade_subscription_t *bsub);
KS_DECLARE(const char *) blade_subscription_channel_get(blade_subscription_t *bsub);
KS_DECLARE(ks_hash_t *) blade_subscription_subscribers_get(blade_subscription_t *bsub);
KS_DECLARE(ks_status_t) blade_subscription_subscribers_add(blade_subscription_t *bsub, const char *nodeid);
diff --git a/libs/libblade/src/include/blade_subscriptionmgr.h b/libs/libblade/src/include/blade_subscriptionmgr.h
index 045130c2e5..0cc811985e 100644
--- a/libs/libblade/src/include/blade_subscriptionmgr.h
+++ b/libs/libblade/src/include/blade_subscriptionmgr.h
@@ -39,12 +39,12 @@ KS_BEGIN_EXTERN_C
KS_DECLARE(ks_status_t) blade_subscriptionmgr_create(blade_subscriptionmgr_t **bsmgrP, blade_handle_t *bh);
KS_DECLARE(ks_status_t) blade_subscriptionmgr_destroy(blade_subscriptionmgr_t **bsmgrP);
KS_DECLARE(blade_handle_t *) blade_subscriptionmgr_handle_get(blade_subscriptionmgr_t *bsmgr);
-KS_DECLARE(blade_subscription_t *) blade_subscriptionmgr_subscription_lookup(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *realm, const char *channel);
-KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *realm, const char *channel);
-KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *realm, const char *channel, const char *subscriber);
-KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_remove(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *realm, const char *channel, const char *subscriber);
+KS_DECLARE(blade_subscription_t *) blade_subscriptionmgr_subscription_lookup(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *channel);
+KS_DECLARE(ks_status_t) blade_subscriptionmgr_subscription_remove(blade_subscriptionmgr_t *bsmgr, const char *protocol, const char *channel);
+KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_add(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *channel, const char *subscriber);
+KS_DECLARE(ks_bool_t) blade_subscriptionmgr_subscriber_remove(blade_subscriptionmgr_t *bsmgr, blade_subscription_t **bsubP, const char *protocol, const char *channel, const char *subscriber);
KS_DECLARE(void) blade_subscriptionmgr_purge(blade_subscriptionmgr_t *bsmgr, const char *target);
-KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t *bsmgr, blade_rpcbroadcast_command_t command, const char *excluded_nodeid, const char *protocol, const char *realm, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data);
+KS_DECLARE(ks_status_t) blade_subscriptionmgr_broadcast(blade_subscriptionmgr_t *bsmgr, blade_rpcbroadcast_command_t command, const char *excluded_nodeid, const char *protocol, const char *channel, const char *event, cJSON *params, blade_rpc_response_callback_t callback, void *data);
KS_END_EXTERN_C
#endif
diff --git a/libs/libblade/src/include/blade_types.h b/libs/libblade/src/include/blade_types.h
index db1c0b3ed2..c806dec27b 100644
--- a/libs/libblade/src/include/blade_types.h
+++ b/libs/libblade/src/include/blade_types.h
@@ -48,7 +48,6 @@ typedef struct blade_rpc_response_s blade_rpc_response_t;
typedef struct blade_connection_s blade_connection_t;
typedef struct blade_session_s blade_session_t;
typedef struct blade_session_callbacks_s blade_session_callbacks_t;
-typedef struct blade_realm_s blade_realm_t;
typedef struct blade_protocol_s blade_protocol_t;
typedef struct blade_channel_s blade_channel_t;
typedef struct blade_subscription_s blade_subscription_t;
@@ -58,7 +57,6 @@ typedef struct blade_transportmgr_s blade_transportmgr_t;
typedef struct blade_rpcmgr_s blade_rpcmgr_t;
typedef struct blade_routemgr_s blade_routemgr_t;
typedef struct blade_subscriptionmgr_s blade_subscriptionmgr_t;
-typedef struct blade_upstreammgr_s blade_upstreammgr_t;
typedef struct blade_mastermgr_s blade_mastermgr_t;
typedef struct blade_connectionmgr_s blade_connectionmgr_t;
typedef struct blade_sessionmgr_s blade_sessionmgr_t;
@@ -106,7 +104,10 @@ typedef enum {
BLADE_SESSION_STATE_RUN,
} blade_session_state_t;
-
+typedef enum {
+ BLADE_CHANNEL_FLAGS_NONE = 0 << 0,
+ BLADE_CHANNEL_FLAGS_PUBLIC = 1 << 0,
+} blade_channel_flags_t;
typedef ks_status_t (*blade_transport_startup_callback_t)(blade_transport_t *bt, config_setting_t *config);
diff --git a/libs/libblade/src/include/blade_upstreammgr.h b/libs/libblade/src/include/blade_upstreammgr.h
deleted file mode 100644
index d662560aff..0000000000
--- a/libs/libblade/src/include/blade_upstreammgr.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2017, Shane Bryldt
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * * Neither the name of the original author; nor the names of any contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _BLADE_UPSTREAMMGR_H_
-#define _BLADE_UPSTREAMMGR_H_
-#include
-
-KS_BEGIN_EXTERN_C
-KS_DECLARE(ks_status_t) blade_upstreammgr_create(blade_upstreammgr_t **bumgrP, blade_handle_t *bh);
-KS_DECLARE(ks_status_t) blade_upstreammgr_destroy(blade_upstreammgr_t **bumgrP);
-KS_DECLARE(blade_handle_t *) blade_upstreammgr_handle_get(blade_upstreammgr_t *bumgr);
-KS_DECLARE(ks_status_t) blade_upstreammgr_localid_set(blade_upstreammgr_t *bumgr, const char *id);
-KS_DECLARE(ks_bool_t) blade_upstreammgr_localid_compare(blade_upstreammgr_t *bumgr, const char *id);
-KS_DECLARE(ks_status_t) blade_upstreammgr_localid_copy(blade_upstreammgr_t *bumgr, ks_pool_t *pool, const char **id);
-KS_DECLARE(ks_bool_t) blade_upstreammgr_session_established(blade_upstreammgr_t *bumgr);
-KS_DECLARE(blade_session_t *) blade_upstreammgr_session_get(blade_upstreammgr_t *bumgr);
-KS_DECLARE(ks_status_t) blade_upstreammgr_masterid_set(blade_upstreammgr_t *bumgr, const char *id);
-KS_DECLARE(ks_bool_t) blade_upstreammgr_masterid_compare(blade_upstreammgr_t *bumgr, const char *id);
-KS_DECLARE(ks_status_t) blade_upstreammgr_masterid_copy(blade_upstreammgr_t *bumgr, ks_pool_t *pool, const char **id);
-KS_DECLARE(ks_bool_t) blade_upstreammgr_masterlocal(blade_upstreammgr_t *bumgr);
-
-KS_END_EXTERN_C
-
-#endif
-
-/* For Emacs:
- * Local Variables:
- * mode:c
- * indent-tabs-mode:t
- * tab-width:4
- * c-basic-offset:4
- * End:
- * For VIM:
- * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
- */
diff --git a/libs/libblade/switchblade/switchblade.c b/libs/libblade/switchblade/switchblade.c
index ae69a24bf8..8a62c3fed3 100644
--- a/libs/libblade/switchblade/switchblade.c
+++ b/libs/libblade/switchblade/switchblade.c
@@ -1,9 +1,28 @@
#include "blade.h"
+#define CONSOLE_INPUT_MAX 512
+
// @todo switch to wait condition once something is being done with the main thread during runtime
ks_bool_t g_shutdown = KS_FALSE;
-void idle(blade_handle_t *bh);
+void loop(blade_handle_t *bh);
+void process_console_input(blade_handle_t *bh, char *line);
+
+typedef void(*command_callback)(blade_handle_t *bh, char *args);
+
+struct command_def_s {
+ const char *cmd;
+ command_callback callback;
+};
+
+void command_quit(blade_handle_t *bh, char *args);
+
+static const struct command_def_s command_defs[] = {
+ { "quit", command_quit },
+
+ { NULL, NULL }
+};
+
int main(int argc, char **argv)
{
@@ -40,7 +59,7 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}
- idle(bh);
+ loop(bh);
blade_handle_destroy(&bh);
@@ -51,13 +70,70 @@ int main(int argc, char **argv)
return 0;
}
-void idle(blade_handle_t *bh)
+void loop(blade_handle_t *bh)
{
+ char buf[CONSOLE_INPUT_MAX];
while (!g_shutdown) {
- ks_sleep_ms(1000);
+ if (!fgets(buf, CONSOLE_INPUT_MAX, stdin)) break;
+
+ for (int index = 0; buf[index]; ++index) {
+ if (buf[index] == '\r' || buf[index] == '\n') {
+ buf[index] = '\0';
+ break;
+ }
+ }
+ process_console_input(bh, buf);
+
+ ks_sleep_ms(100);
}
}
+void parse_argument(char **input, char **arg, char terminator)
+{
+ char *tmp;
+
+ ks_assert(input);
+ ks_assert(*input);
+ ks_assert(arg);
+
+ tmp = *input;
+ *arg = tmp;
+
+ while (*tmp && *tmp != terminator) ++tmp;
+ if (*tmp == terminator) {
+ *tmp = '\0';
+ ++tmp;
+ }
+ *input = tmp;
+}
+
+void process_console_input(blade_handle_t *bh, char *line)
+{
+ char *args = line;
+ char *cmd = NULL;
+ ks_bool_t found = KS_FALSE;
+
+ parse_argument(&args, &cmd, ' ');
+
+ ks_log(KS_LOG_DEBUG, "Command: %s, Args: %s\n", cmd, args);
+
+ for (int32_t index = 0; command_defs[index].cmd; ++index) {
+ if (!strcmp(command_defs[index].cmd, cmd)) {
+ found = KS_TRUE;
+ command_defs[index].callback(bh, args);
+ }
+ }
+ if (!found) ks_log(KS_LOG_INFO, "Command '%s' unknown.\n", cmd);
+}
+
+void command_quit(blade_handle_t *bh, char *args)
+{
+ //ks_assert(bh);
+ //ks_assert(args);
+
+ g_shutdown = KS_TRUE;
+}
+
/* For Emacs:
* Local Variables:
diff --git a/libs/libblade/test/bladec.c b/libs/libblade/test/bladec.c
index cb6a2fb4bc..e5744e3dd8 100644
--- a/libs/libblade/test/bladec.c
+++ b/libs/libblade/test/bladec.c
@@ -66,7 +66,6 @@ ks_bool_t blade_locate_response_handler(blade_rpc_response_t *brpcres, void *dat
cJSON *res_result = NULL;
cJSON *res_result_controllers = NULL;
const char *res_result_protocol = NULL;
- const char *res_result_realm = NULL;
cJSON *params = NULL;
ks_assert(brpcres);
@@ -86,9 +85,6 @@ ks_bool_t blade_locate_response_handler(blade_rpc_response_t *brpcres, void *dat
res_result_protocol = cJSON_GetObjectCstr(res_result, "protocol");
ks_assert(res_result_protocol);
- res_result_realm = cJSON_GetObjectCstr(res_result, "realm");
- ks_assert(res_result_realm);
-
res_result_controllers = cJSON_GetObjectItem(res_result, "controllers");
ks_assert(res_result_controllers);
@@ -97,7 +93,7 @@ ks_bool_t blade_locate_response_handler(blade_rpc_response_t *brpcres, void *dat
for (int index = 0; index < cJSON_GetArraySize(res_result_controllers); ++index) {
cJSON *elem = cJSON_GetArrayItem(res_result_controllers, index);
if (elem->type == cJSON_String) {
- ks_log(KS_LOG_DEBUG, "Session (%s) blade.locate (%s@%s) provider (%s)\n", blade_session_id_get(bs), res_result_protocol, res_result_realm, elem->valuestring);
+ ks_log(KS_LOG_DEBUG, "Session (%s) blade.locate (%s) provider (%s)\n", blade_session_id_get(bs), res_result_protocol, elem->valuestring);
nodeid = elem->valuestring;
}
}
@@ -106,7 +102,7 @@ ks_bool_t blade_locate_response_handler(blade_rpc_response_t *brpcres, void *dat
params = cJSON_CreateObject();
cJSON_AddStringToObject(params, "text", "hello world!");
- blade_handle_rpcexecute(bh, nodeid, "test.echo", res_result_protocol, res_result_realm, params, test_echo_response_handler, NULL);
+ blade_handle_rpcexecute(bh, nodeid, "test.echo", res_result_protocol, params, test_echo_response_handler, NULL);
return KS_FALSE;
}
@@ -285,7 +281,7 @@ void command_execute(blade_handle_t *bh, char *args)
ks_assert(bh);
ks_assert(args);
- blade_handle_rpclocate(bh, "test", "mydomain.com", blade_locate_response_handler, NULL);
+ blade_handle_rpclocate(bh, "test", blade_locate_response_handler, NULL);
}
void command_subscribe(blade_handle_t *bh, char *args)
@@ -297,7 +293,7 @@ void command_subscribe(blade_handle_t *bh, char *args)
channels = cJSON_CreateArray();
cJSON_AddItemToArray(channels, cJSON_CreateString("test"));
- blade_handle_rpcsubscribe(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_ADD, "test", "mydomain.com", channels, blade_subscribe_response_handler, NULL, test_event_request_handler, NULL);
+ blade_handle_rpcsubscribe(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_ADD, "test", channels, blade_subscribe_response_handler, NULL, test_event_request_handler, NULL);
cJSON_Delete(channels);
}
diff --git a/libs/libblade/test/blades.c b/libs/libblade/test/blades.c
index 668d6ad2b7..d81904ebab 100644
--- a/libs/libblade/test/blades.c
+++ b/libs/libblade/test/blades.c
@@ -240,11 +240,11 @@ void command_publish(blade_handle_t *bh, char *args)
ks_assert(bh);
ks_assert(args);
- blade_rpc_create(&brpc, bh, "test.echo", "test", "mydomain.com", test_echo_request_handler, NULL);
+ blade_rpc_create(&brpc, bh, "test.echo", "test", test_echo_request_handler, NULL);
blade_rpcmgr_protocolrpc_add(blade_handle_rpcmgr_get(bh), brpc);
// @todo build up json-based method schema for each protocolrpc registered above, and pass into blade_handle_rpcpublish() to attach to the request, to be stored in the blade_protocol_t tracked by the master node
- blade_handle_rpcpublish(bh, BLADE_RPCPUBLISH_COMMAND_CONTROLLER_ADD, "test", "mydomain.com", NULL, blade_publish_response_handler, NULL);
+ blade_handle_rpcpublish(bh, BLADE_RPCPUBLISH_COMMAND_CONTROLLER_ADD, "test", NULL, blade_publish_response_handler, NULL);
}
void command_broadcast(blade_handle_t *bh, char *args)
@@ -252,7 +252,7 @@ void command_broadcast(blade_handle_t *bh, char *args)
ks_assert(bh);
ks_assert(args);
- blade_handle_rpcbroadcast(bh, "test", "mydomain.com", "channel", "event", NULL, test_broadcast_response_handler, NULL);
+ blade_handle_rpcbroadcast(bh, "test", "channel", "event", NULL, test_broadcast_response_handler, NULL);
}
diff --git a/libs/libblade/test/testcli.c b/libs/libblade/test/testcli.c
index 213c159386..d904c448af 100644
--- a/libs/libblade/test/testcli.c
+++ b/libs/libblade/test/testcli.c
@@ -46,7 +46,6 @@ ks_bool_t test_locate_response_handler(blade_rpc_response_t *brpcres, void *data
cJSON *res_result = NULL;
cJSON *res_result_controllers = NULL;
const char *res_result_protocol = NULL;
- const char *res_result_realm = NULL;
//cJSON *params = NULL;
ks_assert(brpcres);
@@ -66,12 +65,9 @@ ks_bool_t test_locate_response_handler(blade_rpc_response_t *brpcres, void *data
res_result_protocol = cJSON_GetObjectCstr(res_result, "protocol");
ks_assert(res_result_protocol);
- res_result_realm = cJSON_GetObjectCstr(res_result, "realm");
- ks_assert(res_result_realm);
-
res_result_controllers = cJSON_GetObjectItem(res_result, "controllers");
- ks_log(KS_LOG_DEBUG, "Session (%s) locate (%s@%s) response processing\n", blade_session_id_get(bs), res_result_protocol, res_result_realm);
+ ks_log(KS_LOG_DEBUG, "Session (%s) locate (%s) response processing\n", blade_session_id_get(bs), res_result_protocol);
if (res_result_controllers) {
for (int index = 0; index < cJSON_GetArraySize(res_result_controllers); ++index) {
@@ -89,7 +85,7 @@ ks_bool_t test_locate_response_handler(blade_rpc_response_t *brpcres, void *data
g_testcon_nodeid = ks_pstrdup(ks_pool_get(bh), nodeid);
}
- ks_log(KS_LOG_DEBUG, "Session (%s) locate (%s@%s) provider (%s)\n", blade_session_id_get(bs), res_result_protocol, res_result_realm, g_testcon_nodeid);
+ ks_log(KS_LOG_DEBUG, "Session (%s) locate (%s) provider (%s)\n", blade_session_id_get(bs), res_result_protocol, g_testcon_nodeid);
return KS_FALSE;
}
@@ -273,7 +269,7 @@ int main(int argc, char **argv)
if (connected) {
- // @todo use session state change callback to know when the session is ready and the realm(s) available from blade.connect
+ // @todo use session state change callback to know when the session is ready after blade.connect
ks_sleep_ms(3000);
}
}
@@ -356,7 +352,7 @@ void command_locate(blade_handle_t *bh, char *args)
ks_assert(bh);
ks_assert(args);
- blade_handle_rpclocate(bh, "test", "mydomain.com", test_locate_response_handler, NULL);
+ blade_handle_rpclocate(bh, "test", test_locate_response_handler, NULL);
}
void command_join(blade_handle_t *bh, char *args)
@@ -372,7 +368,7 @@ void command_join(blade_handle_t *bh, char *args)
}
params = cJSON_CreateObject();
- blade_handle_rpcexecute(bh, g_testcon_nodeid, "test.join", "test", "mydomain.com", params, test_join_response_handler, NULL);
+ blade_handle_rpcexecute(bh, g_testcon_nodeid, "test.join", "test", params, test_join_response_handler, NULL);
cJSON_Delete(params);
}
@@ -388,7 +384,7 @@ void command_subscribe(blade_handle_t *bh, char *args)
channels = cJSON_CreateArray();
cJSON_AddItemToArray(channels, cJSON_CreateString("channel"));
if (args && args[0]) cJSON_AddItemToArray(channels, cJSON_CreateString(args));
- blade_handle_rpcsubscribe(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_ADD, "test", "mydomain.com", channels, NULL, NULL, test_channel_handler, NULL);
+ blade_handle_rpcsubscribe(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_ADD, "test", channels, NULL, NULL, test_channel_handler, NULL);
cJSON_Delete(channels);
}
@@ -404,7 +400,7 @@ void command_unsubscribe(blade_handle_t *bh, char *args)
channels = cJSON_CreateArray();
cJSON_AddItemToArray(channels, cJSON_CreateString("channel"));
if (args && args[0]) cJSON_AddItemToArray(channels, cJSON_CreateString(args));
- blade_handle_rpcsubscribe(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_REMOVE, "test", "mydomain.com", channels, test_subscribe_response_handler, NULL, test_channel_handler, NULL);
+ blade_handle_rpcsubscribe(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_REMOVE, "test", channels, test_subscribe_response_handler, NULL, test_channel_handler, NULL);
cJSON_Delete(channels);
}
@@ -421,7 +417,7 @@ void command_leave(blade_handle_t *bh, char *args)
}
params = cJSON_CreateObject();
- blade_handle_rpcexecute(bh, g_testcon_nodeid, "test.leave", "test", "mydomain.com", params, test_leave_response_handler, NULL);
+ blade_handle_rpcexecute(bh, g_testcon_nodeid, "test.leave", "test", params, test_leave_response_handler, NULL);
cJSON_Delete(params);
}
@@ -443,7 +439,8 @@ void command_talk(blade_handle_t *bh, char *args)
params = cJSON_CreateObject();
cJSON_AddStringToObject(params, "text", args);
- blade_handle_rpcexecute(bh, g_testcon_nodeid, "test.talk", "test", "mydomain.com", params, test_talk_response_handler, NULL);
+ //blade_handle_rpcexecute(bh, g_testcon_nodeid, "test.talk", "test", params, test_talk_response_handler, NULL);
+ blade_handle_rpcexecute(bh, "blade:testcon@freeswitch.com", "test.talk", "test", params, test_talk_response_handler, NULL);
cJSON_Delete(params);
}
diff --git a/libs/libblade/test/testcon.c b/libs/libblade/test/testcon.c
index 3394576da9..4dffa70330 100644
--- a/libs/libblade/test/testcon.c
+++ b/libs/libblade/test/testcon.c
@@ -16,15 +16,13 @@ struct command_def_s {
};
void command_quit(blade_handle_t *bh, char *args);
-void command_channeladd(blade_handle_t *bh, char *args);
-void command_channelremove(blade_handle_t *bh, char *args);
void command_presence(blade_handle_t *bh, char *args);
+void command_identity(blade_handle_t *bh, char *args);
static const struct command_def_s command_defs[] = {
{ "quit", command_quit },
- { "channeladd", command_channeladd },
- { "channelremove", command_channelremove },
{ "presence", command_presence },
+ { "identity", command_identity },
{ NULL, NULL }
};
@@ -175,7 +173,7 @@ ks_bool_t test_join_request_handler(blade_rpc_request_t *brpcreq, void *data)
cJSON_AddItemToArray(channels, cJSON_CreateString((const char *)key));
}
- blade_handle_rpcauthorize(bh, requester_nodeid, KS_FALSE, "test", "mydomain.com", channels, NULL, NULL);
+ blade_handle_rpcauthorize(bh, requester_nodeid, KS_FALSE, "test", channels, NULL, NULL);
cJSON_Delete(channels);
@@ -193,7 +191,7 @@ ks_bool_t test_join_request_handler(blade_rpc_request_t *brpcreq, void *data)
cJSON_AddStringToObject(params, "joiner-nodeid", requester_nodeid);
- blade_handle_rpcbroadcast(bh, "test", "mydomain.com", "channel", "join", params, NULL, NULL);
+ blade_handle_rpcbroadcast(bh, "test", "channel", "join", params, NULL, NULL);
cJSON_Delete(params);
@@ -245,7 +243,7 @@ ks_bool_t test_leave_request_handler(blade_rpc_request_t *brpcreq, void *data)
cJSON_AddItemToArray(channels, cJSON_CreateString((const char *)key));
}
- blade_handle_rpcauthorize(bh, requester_nodeid, KS_TRUE, "test", "mydomain.com", channels, NULL, NULL);
+ blade_handle_rpcauthorize(bh, requester_nodeid, KS_TRUE, "test", channels, NULL, NULL);
cJSON_Delete(channels);
@@ -263,7 +261,7 @@ ks_bool_t test_leave_request_handler(blade_rpc_request_t *brpcreq, void *data)
cJSON_AddStringToObject(params, "leaver-nodeid", requester_nodeid);
- blade_handle_rpcbroadcast(bh, "test", "mydomain.com", "channel", "leave", params, NULL, NULL);
+ blade_handle_rpcbroadcast(bh, "test", "channel", "leave", params, NULL, NULL);
cJSON_Delete(params);
@@ -318,7 +316,7 @@ ks_bool_t test_talk_request_handler(blade_rpc_request_t *brpcreq, void *data)
cJSON_AddStringToObject(params, "talker-nodeid", requester_nodeid);
- blade_handle_rpcbroadcast(bh, "test", "mydomain.com", "channel", "talk", params, NULL, NULL);
+ blade_handle_rpcbroadcast(bh, "test", "channel", "talk", params, NULL, NULL);
cJSON_Delete(params);
@@ -329,7 +327,6 @@ ks_bool_t test_presence_request_handler(blade_rpc_request_t *brpcreq, void *data
{
blade_handle_t *bh = NULL;
blade_session_t *bs = NULL;
- const char *realm = NULL;
const char *protocol = NULL;
const char *channel = NULL;
const char *event = NULL;
@@ -345,7 +342,6 @@ ks_bool_t test_presence_request_handler(blade_rpc_request_t *brpcreq, void *data
bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bh), blade_rpc_request_sessionid_get(brpcreq));
ks_assert(bs);
- realm = blade_rpcbroadcast_request_realm_get(brpcreq);
protocol = blade_rpcbroadcast_request_protocol_get(brpcreq);
channel = blade_rpcbroadcast_request_channel_get(brpcreq);
event = blade_rpcbroadcast_request_event_get(brpcreq);
@@ -353,7 +349,27 @@ ks_bool_t test_presence_request_handler(blade_rpc_request_t *brpcreq, void *data
params = blade_rpcbroadcast_request_params_get(brpcreq);
nodeid = cJSON_GetObjectCstr(params, "nodeid");
- ks_log(KS_LOG_DEBUG, "Session (%s) presence (%s@%s/%s/%s for %s) request processing\n", blade_session_id_get(bs), protocol, realm, channel, event, nodeid);
+ ks_log(KS_LOG_DEBUG, "Session (%s) presence (protocol %s, channel %s, event %s for %s) request processing\n", blade_session_id_get(bs), protocol, channel, event, nodeid);
+
+ return KS_FALSE;
+}
+
+ks_bool_t test_register_response_handler(blade_rpc_response_t *brpcres, void *data)
+{
+ blade_handle_t *bh = NULL;
+ blade_session_t *bs = NULL;
+
+ ks_assert(brpcres);
+
+ bh = blade_rpc_response_handle_get(brpcres);
+ ks_assert(bh);
+
+ bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bh), blade_rpc_response_sessionid_get(brpcres));
+ ks_assert(bs);
+
+ ks_log(KS_LOG_DEBUG, "Session (%s) register response processing\n", blade_session_id_get(bs));
+
+ blade_session_read_unlock(bs);
return KS_FALSE;
}
@@ -418,23 +434,27 @@ int main(int argc, char **argv)
if (connected) {
cJSON *channels = NULL;
+ cJSON *entry = NULL;
- // @todo use session state change callback to know when the session is ready and the realm(s) available from blade.connect, this hack temporarily ensures it's ready before trying to publish upstream
+ // @todo use session state change callback to know when the session is ready after blade.connect, this hack temporarily ensures it's ready before trying to publish upstream
ks_sleep_ms(3000);
- blade_rpc_create(&brpc, bh, "test.join", "test", "mydomain.com", test_join_request_handler, (void *)g_test);
+ blade_rpc_create(&brpc, bh, "test.join", "test", test_join_request_handler, (void *)g_test);
blade_rpcmgr_protocolrpc_add(blade_handle_rpcmgr_get(bh), brpc);
- blade_rpc_create(&brpc, bh, "test.leave", "test", "mydomain.com", test_leave_request_handler, (void *)g_test);
+ blade_rpc_create(&brpc, bh, "test.leave", "test", test_leave_request_handler, (void *)g_test);
blade_rpcmgr_protocolrpc_add(blade_handle_rpcmgr_get(bh), brpc);
- blade_rpc_create(&brpc, bh, "test.talk", "test", "mydomain.com", test_talk_request_handler, (void *)g_test);
+ blade_rpc_create(&brpc, bh, "test.talk", "test", test_talk_request_handler, (void *)g_test);
blade_rpcmgr_protocolrpc_add(blade_handle_rpcmgr_get(bh), brpc);
channels = cJSON_CreateArray();
- cJSON_AddItemToArray(channels, cJSON_CreateString("channel"));
+ entry = cJSON_CreateObject();
+ cJSON_AddStringToObject(entry, "name", "channel");
+ cJSON_AddNumberToObject(entry, "flags", BLADE_CHANNEL_FLAGS_NONE);
+ cJSON_AddItemToArray(channels, entry);
- blade_handle_rpcpublish(bh, BLADE_RPCPUBLISH_COMMAND_CONTROLLER_ADD, "test", "mydomain.com", channels, test_publish_response_handler, (void *)g_test);
+ blade_handle_rpcpublish(bh, BLADE_RPCPUBLISH_COMMAND_CONTROLLER_ADD, "test", channels, test_publish_response_handler, (void *)g_test);
cJSON_Delete(channels);
}
@@ -515,51 +535,6 @@ void command_quit(blade_handle_t *bh, char *args)
g_shutdown = KS_TRUE;
}
-void command_channeladd(blade_handle_t *bh, char *args)
-{
- cJSON *channels = NULL;
-
- ks_assert(bh);
- ks_assert(args);
-
- if (!args[0]) {
- ks_log(KS_LOG_INFO, "Requires channel argument");
- return;
- }
-
- ks_hash_insert(g_test->channels, (void *)ks_pstrdup(g_test->pool, args), (void *)KS_TRUE);
-
- channels = cJSON_CreateArray();
- cJSON_AddItemToArray(channels, cJSON_CreateString(args));
-
- blade_handle_rpcpublish(bh, BLADE_RPCPUBLISH_COMMAND_CHANNEL_ADD, "test", "mydomain.com", channels, test_publish_response_handler, (void *)g_test);
-
- cJSON_Delete(channels);
-}
-
-void command_channelremove(blade_handle_t *bh, char *args)
-{
- cJSON *channels = NULL;
-
- ks_assert(bh);
- ks_assert(args);
-
- if (!args[0]) {
- ks_log(KS_LOG_INFO, "Requires channel argument");
- return;
- }
-
-
- if (ks_hash_remove(g_test->channels, (void *)args)) {
- channels = cJSON_CreateArray();
- cJSON_AddItemToArray(channels, cJSON_CreateString(args));
-
- blade_handle_rpcpublish(bh, BLADE_RPCPUBLISH_COMMAND_CHANNEL_REMOVE, "test", "mydomain.com", channels, test_publish_response_handler, (void *)g_test);
-
- cJSON_Delete(channels);
- }
-}
-
void command_presence(blade_handle_t *bh, char *args)
{
cJSON *channels = NULL;
@@ -571,7 +546,15 @@ void command_presence(blade_handle_t *bh, char *args)
cJSON_AddItemToArray(channels, cJSON_CreateString("join"));
cJSON_AddItemToArray(channels, cJSON_CreateString("leave"));
- blade_handle_rpcsubscribe(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_ADD, "presence", "blade", channels, NULL, NULL, test_presence_request_handler, (void *)g_test);
+ blade_handle_rpcsubscribe(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_ADD, "blade.presence", channels, NULL, NULL, test_presence_request_handler, (void *)g_test);
+}
+
+void command_identity(blade_handle_t *bh, char *args)
+{
+ ks_assert(bh);
+ ks_assert(args);
+
+ blade_handle_rpcregister(bh, "blade:testcon@freeswitch.com", test_register_response_handler, NULL);
}
/* For Emacs:
diff --git a/libs/libks/src/ks_ssl.c b/libs/libks/src/ks_ssl.c
index 5db491d4d5..4f3efafd8f 100644
--- a/libs/libks/src/ks_ssl.c
+++ b/libs/libks/src/ks_ssl.c
@@ -109,6 +109,7 @@ KS_DECLARE(void) ks_ssl_destroy_ssl_locks(void)
#ifdef _WINDOWS
SSL_COMP_free_compression_methods();
#endif
+ ERR_free_strings();
EVP_cleanup();
}