]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-10167: Implemented identity registration and routing, removed subrealms to be...
authorShane Bryldt <astaelan@gmail.com>
Thu, 21 Sep 2017 04:07:34 +0000 (22:07 -0600)
committerShane Bryldt <astaelan@gmail.com>
Thu, 21 Sep 2017 04:07:34 +0000 (22:07 -0600)
38 files changed:
libs/libblade/libblade.vcxproj
libs/libblade/libblade.vcxproj.filters
libs/libblade/src/blade_channel.c
libs/libblade/src/blade_identity.c
libs/libblade/src/blade_mastermgr.c
libs/libblade/src/blade_protocol.c
libs/libblade/src/blade_realm.c [deleted file]
libs/libblade/src/blade_routemgr.c
libs/libblade/src/blade_rpc.c
libs/libblade/src/blade_rpcmgr.c
libs/libblade/src/blade_session.c
libs/libblade/src/blade_sessionmgr.c
libs/libblade/src/blade_stack.c
libs/libblade/src/blade_subscription.c
libs/libblade/src/blade_subscriptionmgr.c
libs/libblade/src/blade_transport_wss.c
libs/libblade/src/blade_upstreammgr.c [deleted file]
libs/libblade/src/include/blade.h
libs/libblade/src/include/blade_channel.h
libs/libblade/src/include/blade_identity.h
libs/libblade/src/include/blade_mastermgr.h
libs/libblade/src/include/blade_protocol.h
libs/libblade/src/include/blade_realm.h [deleted file]
libs/libblade/src/include/blade_routemgr.h
libs/libblade/src/include/blade_rpc.h
libs/libblade/src/include/blade_rpcmgr.h
libs/libblade/src/include/blade_session.h
libs/libblade/src/include/blade_stack.h
libs/libblade/src/include/blade_subscription.h
libs/libblade/src/include/blade_subscriptionmgr.h
libs/libblade/src/include/blade_types.h
libs/libblade/src/include/blade_upstreammgr.h [deleted file]
libs/libblade/switchblade/switchblade.c
libs/libblade/test/bladec.c
libs/libblade/test/blades.c
libs/libblade/test/testcli.c
libs/libblade/test/testcon.c
libs/libks/src/ks_ssl.c

index 8cb58199b14b08f5b8c2613f59b6340e92e5b9df..33a94930017775e34d36942c34858c865d9fb929 100644 (file)
     <ClCompile Include="src\blade_connectionmgr.c" />
     <ClCompile Include="src\blade_identity.c" />
     <ClCompile Include="src\blade_mastermgr.c" />
-    <ClCompile Include="src\blade_realm.c" />
     <ClCompile Include="src\blade_routemgr.c" />
     <ClCompile Include="src\blade_rpc.c" />
     <ClCompile Include="src\blade_protocol.c" />
     <ClCompile Include="src\blade_stack.c" />
     <ClCompile Include="src\blade_transport.c" />
     <ClCompile Include="src\blade_tuple.c" />
-    <ClCompile Include="src\blade_upstreammgr.c" />
     <ClCompile Include="src\unqlite.c" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\include\blade_connectionmgr.h" />
     <ClInclude Include="src\include\blade_identity.h" />
     <ClInclude Include="src\include\blade_mastermgr.h" />
-    <ClInclude Include="src\include\blade_realm.h" />
     <ClInclude Include="src\include\blade_routemgr.h" />
     <ClInclude Include="src\include\blade_rpc.h" />
     <ClInclude Include="src\include\blade_protocol.h" />
     <ClInclude Include="src\include\blade_transport.h" />
     <ClInclude Include="src\include\blade_tuple.h" />
     <ClInclude Include="src\include\blade_types.h" />
-    <ClInclude Include="src\include\blade_upstreammgr.h" />
     <ClInclude Include="src\include\unqlite.h" />
   </ItemGroup>
   <ItemGroup>
index f3392d90c6bc1590bae6967bd54ff334d96e292c..c8d2468fe34e79236765727a9088a67551759c99 100644 (file)
@@ -60,9 +60,6 @@
     <ClCompile Include="src\blade_subscriptionmgr.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="src\blade_upstreammgr.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="src\blade_mastermgr.c">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -75,9 +72,6 @@
     <ClCompile Include="src\blade_tuple.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="src\blade_realm.c">
-      <Filter>Source Files</Filter>
-    </ClCompile>
     <ClCompile Include="src\blade_channel.c">
       <Filter>Source Files</Filter>
     </ClCompile>
     <ClInclude Include="src\include\blade_subscriptionmgr.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="src\include\blade_upstreammgr.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="src\include\blade_mastermgr.h">
       <Filter>Header Files</Filter>
     </ClInclude>
     <ClInclude Include="src\include\blade_tuple.h">
       <Filter>Header Files</Filter>
     </ClInclude>
-    <ClInclude Include="src\include\blade_realm.h">
-      <Filter>Header Files</Filter>
-    </ClInclude>
     <ClInclude Include="src\include\blade_channel.h">
       <Filter>Header Files</Filter>
     </ClInclude>
index 419d9e89ca3c409fa9db2001ae6caedcd1b0523f..c97656380343bc851859ff401d595aa9563a2866 100644 (file)
@@ -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);
index 49254b90714bdfbe9d5d4af01ecff7ecc5dcc741..582f047a3bca13528170c2e78f78079e14b0b088 100644 (file)
@@ -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
+       // <scheme:[//]> [user@] <host> [:port] [/path] [;param1=value1] [;param2=value2]
+
+       // scheme is mandatory to simplify the parser for now, it must start with mandatory: <scheme>:
+       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;
+       }
+
+       // next component may be the user or the host, so it may start with optional: <user>@
+       // 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;
+       }
+
+       // grab the terminator and null terminate for the next component
+       terminator = *tmp2;
+       *tmp2++ = '\0';
+
+       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 ((tmp = strchr(tmp, '?'))) {
-               *tmp++ = '\0';
+       if (terminator == '/') {
+               // path terminator
+               bi->path = tmp;
 
-               while (tmp) {
-                       char *key = tmp;
-                       char *val = NULL;
-                       if (!(tmp = strchr(tmp, '='))) return KS_STATUS_FAIL;
+               // 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';
-                       val = tmp;
-                       if ((tmp = strchr(tmp, '&'))) {
+
+                       // 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';
                        }
 
-                       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);
-               }
+                       // 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);
 }
 
index 61337c98e8acee8db5e782d1bcef5c6b462ee5ff..8316216fe83ceb7d1ba18867c6d067915db8bf08 100644 (file)
 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);
-
-       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);
+       ks_hash_write_lock(bmmgr->protocols);
 
-               blade_realm_write_lock(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;
 
-               for (ks_hash_iterator_t *it2 = blade_realm_protocols_iterator(br, KS_UNLOCKED); it2; it2 = ks_hash_next(&it2)) {
-                       const char *protocol = NULL;
-                       blade_protocol_t *bp = NULL;
+               ks_hash_this(it, (const void **)&protocol, NULL, (void **)&bp);
 
-                       ks_hash_this(it2, (const void **)&protocol, NULL, (void **)&bp);
-
-                       blade_protocol_write_lock(bp);
+               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);
-                               }
-                               else {
-                                       // @todo not the last controller, may need to propagate that the controller is no longer available?
-                               }
+               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;
                        }
-               }
-
-               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);
+                       else {
+                               // @todo not the last controller, may need to propagate that the controller is no longer available?
                        }
-                       ks_hash_destroy(&cleanup);
                }
-
-               blade_realm_write_unlock(br);
+               if (unlock) blade_protocol_write_unlock(bp);
        }
 
-       ks_hash_write_unlock(bmmgr->realms);
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_mastermgr_realm_add(blade_mastermgr_t *bmmgr, blade_realm_t *realm)
-{
-       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);
+       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;
 
-       return KS_STATUS_SUCCESS;
-}
+                       ks_hash_this(it2, (const void **)&protocol, NULL, (void **)&bp);
 
-KS_DECLARE(ks_bool_t) blade_mastermgr_realm_remove(blade_mastermgr_t *bmmgr, const char *realm)
-{
-       ks_bool_t ret = KS_FALSE;
+                       blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE, NULL, protocol, NULL, NULL, NULL, NULL, NULL);
 
-       ks_assert(bmmgr);
-       ks_assert(realm);
+                       ks_log(KS_LOG_DEBUG, "Protocol Removed: %s\n", protocol);
+                       blade_protocol_write_unlock(bp);
 
-       if (ks_hash_remove(bmmgr->realms, (void *)realm)) {
-               ret = KS_TRUE;
-               ks_log(KS_LOG_DEBUG, "Realm Removed: %s\n", realm);
+                       ks_hash_remove(bmmgr->protocols, (void *)protocol);
+               }
+               ks_hash_destroy(&cleanup);
        }
 
-       return ret;
+       ks_hash_write_unlock(bmmgr->protocols);
+
+       return KS_STATUS_SUCCESS;
 }
 
-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(blade_protocol_t *) blade_mastermgr_protocol_lookup(blade_mastermgr_t *bmmgr, 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_realm_protocol_lookup(br, protocol, KS_TRUE);
-       if (bp) {
-               // @todo deal with exclusive stuff when the protocol is already registered
-       }
+       bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
 
-       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;
+       bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)protocol, KS_UNLOCKED);
+       if (!bp) {
+               ret = KS_STATUS_NOT_FOUND;
                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);
+       blade_protocol_write_lock(bp);
 
-                               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
-                       }
+       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);
        }
 
+       blade_protocol_write_unlock(bp);
+
+       if (remove) ks_hash_remove(bmmgr->protocols, (void *)protocol);
+
 done:
-       ks_hash_read_unlock(bmmgr->realms);
+       ks_hash_write_unlock(bmmgr->protocols);
 
        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_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_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) {
+       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);
-
-       br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
-       if (!br) {
-               ret = KS_STATUS_FAIL;
-               goto done;
-       }
+       ks_hash_read_lock(bmmgr->protocols);
 
-       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;
 }
index 79efbf1895fed5dbec371187ba2a62427cb51ea2..d27840166cb2c65763bb8e07d8e5610599651cf6 100644 (file)
@@ -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 (file)
index 149b57e..0000000
+++ /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:
- */
index 277908a5998b33e7950a1b2da2543ac8b8fc45e4..3b1eeb4cf956051a527703074f9c74761e4e4c91 100644 (file)
 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
index 51a525164562ddafd75cb79f05ea633a4a9db56a..9e92fbc01617b4f9cfcddb7285ecadd2ed4de6e3 100644 (file)
@@ -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);
index 101128ddba360bdc9f21a7bb9bd96e7e8d0568b3..a8014388beca31450e1a8a1656d2ddb81e8bb9b5 100644 (file)
@@ -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);
index 462c4713a4a25c67ecc6088618885bcc94fb8a8b..99626209e24557f8cc58d3bb2fff220c819e5795 100644 (file)
@@ -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;
index 5e13bc69a28575936926bda69e69d8f7b8c832da..593317c37de355946a629591846b7abbce6ffbc3 100644 (file)
@@ -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);
index 929c6cb592c37679e8d98d68ad0c48aaabae4d48..a3bfecbf4076edcc1a7d4f2e28fadf1259b55916 100644 (file)
@@ -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.register", NULL, blade_rpcregister_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.publish", NULL, blade_rpcpublish_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.authorize", NULL, blade_rpcauthorize_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.locate", NULL, blade_rpclocate_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.execute", NULL, blade_rpcexecute_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.subscribe", NULL, blade_rpcsubscribe_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.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);
 
-       cJSON_AddStringToObject(req_params, "requester-nodeid", id);
-       ks_pool_free(&id);
+       blade_routemgr_local_pack(bh->routemgr, req_params, "requester-nodeid");
 
-       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);
-
-       cJSON_AddStringToObject(req_params, "requester-nodeid", id);
-       ks_pool_free(&id);
+       blade_routemgr_local_pack(bh->routemgr, req_params, "requester-nodeid");
 
-       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);
-
-       cJSON_AddStringToObject(req_params, "requester-nodeid", id);
-       ks_pool_free(&id);
 
-       blade_upstreammgr_masterid_copy(bh->upstreammgr, pool, &id);
-       ks_assert(id);
+       blade_routemgr_local_pack(bh->routemgr, req_params, "requester-nodeid");
 
-       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)
index 153551e7718d91853c8a031c4d6fee17203e59f4..19c6fdd5d1da7a531fe51061eb09bf24da464433 100644 (file)
@@ -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)
index e09dabfaa0703e902cc310f26706626785f68a01..64105239cd182a345d97c681ec843655075728a7 100644 (file)
@@ -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);
 
index db55ca4e441cdd78cfbb38c1bafe2647c32aa596..ea123f4a0e3738de865f69c1d18ff948ca9883af 100644 (file)
@@ -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 (file)
index bcdee57..0000000
+++ /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:
- */
index eb5d7d222b880a5dc5899e60e7f2fa94ab95b374..b47ace61534bc3fd51b0973341d4af9293709946 100644 (file)
@@ -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"
index 64885f6dd5258f48198db2318c555030f6d277d9..660748dd36823a26b09a7888f1cba2ef51bb14d9 100644 (file)
 #include <blade.h>
 
 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);
index 8d8329459e8591a512f219e85a61bc927c7797e3..bdef1d203edce1c54effe276ac4b0618a7022a61 100644 (file)
@@ -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
index 12a97d220efffe5d49b7d51afccd0d848723edfd..11242aee9acea076e5509d4131f5ffbde479cc84 100644 (file)
@@ -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
index cdbf74ce538f5c33504c6d6c1f3bc5c0b07f26f9..bb59a1da6376bea66ef7fa7387ab1efd038915d5 100644 (file)
@@ -36,9 +36,8 @@
 #include <blade.h>
 
 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 (file)
index 1e70f5c..0000000
+++ /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 <blade.h>
-
-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:
- */
index 9f7830a020b3c13d52c036a0c8c1cacc77de0cd8..c75426c18307829bc12e9deb20a07cc63b52490e 100644 (file)
@@ -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
index a966088af4cc4d21a921dc1d6a0aa7e10d5b819b..69e83344b2333f28affe14fe8b6f2da6ebbf99e8 100644 (file)
 #include <blade.h>
 
 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);
 
index b45fb6439f1d069628ccf008dc62e71f9b036929..2d931898129609c0afe5243d1b1d1f9c01aa0ad8 100644 (file)
@@ -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);
index b84ac257ad0495adaff748abe8aed7a8b63018eb..4bdbe8a85ccdf7dec61a45d88523303269fa30a7 100644 (file)
@@ -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);
index 4e9c03438e6b8a4e0109d7075dd00118f848f972..4a8df5c835dd26ac6da7493c87d1a4284f60ccc8 100644 (file)
@@ -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);
index 96052a744e1b449958be6e39cc877a3be5b5381c..5c591941bd926d69452b77830930b0d2ed4b3ba6 100644 (file)
 #include <blade.h>
 
 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);
index 045130c2e507f6e416edf704695a8df575c85fa2..0cc811985e142f3848f9a859a3a54e574b67db18 100644 (file)
@@ -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
index db1c0b3ed2a7f9e5457dc7c56689b76a63806336..c806dec27bd44a21081e70392f9393a3ba0dffb9 100644 (file)
@@ -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 (file)
index d662560..0000000
+++ /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 <blade.h>
-
-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:
- */
index ae69a24bf82df599ddb6ea21a222c877da8b1bd4..8a62c3fed3b54348cc9742bdb0354a39d7b156f6 100644 (file)
@@ -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:
index cb6a2fb4bcc03fe2aa83a7482cd6155c3d3316ea..e5744e3dd812901ba27e524c2988b754e595c01d 100644 (file)
@@ -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);
 }
 
index 668d6ad2b77b1885c77fd03f10bcaaa95bbf9691..d81904ebabf8653a2b73fe48afb61d6b89045f3e 100644 (file)
@@ -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);
 }
 
 
index 213c1593863a3eaee0bf640403d09f831cb7f61a..d904c448af359d639291f44d3d949455e6fdc91e 100644 (file)
@@ -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);
 }
 
index 3394576da9eacc9bd999cafba05e0657c82b56ea..4dffa70330bf20787a7054b46722cd036d378a80 100644 (file)
@@ -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,63 +535,26 @@ void command_quit(blade_handle_t *bh, char *args)
        g_shutdown = KS_TRUE;
 }
 
-void command_channeladd(blade_handle_t *bh, char *args)
+void command_presence(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_AddItemToArray(channels, cJSON_CreateString("join"));
+       cJSON_AddItemToArray(channels, cJSON_CreateString("leave"));
 
-               cJSON_Delete(channels);
-       }
+       blade_handle_rpcsubscribe(bh, BLADE_RPCSUBSCRIBE_COMMAND_SUBSCRIBER_ADD, "blade.presence", channels, NULL, NULL, test_presence_request_handler, (void *)g_test);
 }
 
-void command_presence(blade_handle_t *bh, char *args)
+void command_identity(blade_handle_t *bh, char *args)
 {
-       cJSON *channels = NULL;
-
        ks_assert(bh);
        ks_assert(args);
 
-       channels = cJSON_CreateArray();
-       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_rpcregister(bh, "blade:testcon@freeswitch.com", test_register_response_handler, NULL);
 }
 
 /* For Emacs:
index 5db491d4d5a33ca35542738d707ba0ee19616e90..4f3efafd8f1ba9f7175fda4b445d15c51ee88a12 100644 (file)
@@ -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();
 }