]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-10167: Temporary commit to retain changes before removing concept of realm/subreal...
authorShane Bryldt <astaelan@gmail.com>
Wed, 13 Sep 2017 14:41:40 +0000 (08:41 -0600)
committerShane Bryldt <astaelan@gmail.com>
Wed, 13 Sep 2017 14:41:40 +0000 (08:41 -0600)
22 files changed:
libs/libblade/libblade.vcxproj
libs/libblade/libblade.vcxproj.filters
libs/libblade/src/blade_channel.c [new file with mode: 0644]
libs/libblade/src/blade_mastermgr.c
libs/libblade/src/blade_module_master.c [deleted file]
libs/libblade/src/blade_protocol.c
libs/libblade/src/blade_realm.c [new file with mode: 0644]
libs/libblade/src/blade_routemgr.c
libs/libblade/src/blade_session.c
libs/libblade/src/blade_sessionmgr.c
libs/libblade/src/blade_stack.c
libs/libblade/src/blade_transport_wss.c
libs/libblade/src/blade_upstreammgr.c
libs/libblade/src/include/blade.h
libs/libblade/src/include/blade_channel.h [moved from libs/libblade/src/include/blade_module_master.h with 66% similarity]
libs/libblade/src/include/blade_mastermgr.h
libs/libblade/src/include/blade_protocol.h
libs/libblade/src/include/blade_realm.h [new file with mode: 0644]
libs/libblade/src/include/blade_stack.h
libs/libblade/src/include/blade_types.h
libs/libblade/src/include/blade_upstreammgr.h
libs/libblade/test/testcon.c

index 43715b542a5d0e418f728fca3424ed40734c79e2..8cb58199b14b08f5b8c2613f59b6340e92e5b9df 100644 (file)
   </ItemDefinitionGroup>
   <ItemGroup>
     <ClCompile Include="src\blade.c" />
+    <ClCompile Include="src\blade_channel.c" />
     <ClCompile Include="src\blade_connection.c" />
     <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" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\include\blade.h" />
+    <ClInclude Include="src\include\blade_channel.h" />
     <ClInclude Include="src\include\blade_connection.h" />
     <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" />
index 2f896185bc21800f876f81ca3c52c4438da81a42..f3392d90c6bc1590bae6967bd54ff334d96e292c 100644 (file)
     <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>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\include\unqlite.h">
     <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>
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/libs/libblade/src/blade_channel.c b/libs/libblade/src/blade_channel.c
new file mode 100644 (file)
index 0000000..419d9e8
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ * 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_channel_s {
+       const char *name;
+       ks_rwl_t *lock;
+       ks_hash_t *authorizations;
+};
+
+
+static void blade_channel_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
+{
+       blade_channel_t *bc = (blade_channel_t *)ptr;
+
+       ks_assert(bc);
+
+       switch (action) {
+       case KS_MPCL_ANNOUNCE:
+               break;
+       case KS_MPCL_TEARDOWN:
+               if (bc->name) ks_pool_free(&bc->name);
+               if (bc->lock) ks_rwl_destroy(&bc->lock);
+               if (bc->authorizations) ks_hash_destroy(&bc->authorizations);
+               break;
+       case KS_MPCL_DESTROY:
+               break;
+       }
+}
+
+KS_DECLARE(ks_status_t) blade_channel_create(blade_channel_t **bcP, ks_pool_t *pool, const char *name)
+{
+       blade_channel_t *bc = NULL;
+
+       ks_assert(bcP);
+       ks_assert(pool);
+       ks_assert(name);
+
+       bc = ks_pool_alloc(pool, sizeof(blade_channel_t));
+       bc->name = ks_pstrdup(pool, name);
+
+       ks_rwl_create(&bc->lock, pool);
+       ks_assert(bc->lock);
+
+       ks_hash_create(&bc->authorizations, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
+       ks_assert(bc->authorizations);
+
+       ks_pool_set_cleanup(bc, NULL, blade_channel_cleanup);
+
+       *bcP = bc;
+
+       return KS_STATUS_SUCCESS;
+}
+
+KS_DECLARE(ks_status_t) blade_channel_destroy(blade_channel_t **bcP)
+{
+       ks_assert(bcP);
+       ks_assert(*bcP);
+
+       ks_pool_free(bcP);
+
+       return KS_STATUS_SUCCESS;
+}
+
+KS_DECLARE(const char *) blade_channel_name_get(blade_channel_t *bc)
+{
+       ks_assert(bc);
+       return bc->name;
+}
+
+KS_DECLARE(ks_status_t) blade_channel_read_lock(blade_channel_t *bc)
+{
+       ks_assert(bc);
+       return ks_rwl_read_lock(bc->lock);
+}
+
+KS_DECLARE(ks_status_t) blade_channel_read_unlock(blade_channel_t *bc)
+{
+       ks_assert(bc);
+       return ks_rwl_read_unlock(bc->lock);
+}
+
+KS_DECLARE(ks_status_t) blade_channel_write_lock(blade_channel_t *bc)
+{
+       ks_assert(bc);
+       return ks_rwl_write_lock(bc->lock);
+}
+
+KS_DECLARE(ks_status_t) blade_channel_write_unlock(blade_channel_t *bc)
+{
+       ks_assert(bc);
+       return ks_rwl_write_unlock(bc->lock);
+}
+
+KS_DECLARE(ks_bool_t) blade_channel_authorization_verify(blade_channel_t *bc, const char *target)
+{
+       ks_bool_t authorized = KS_FALSE;
+
+       ks_assert(bc);
+       ks_assert(target);
+
+       authorized = (ks_bool_t)(uintptr_t)ks_hash_search(bc->authorizations, (void *)target, KS_READLOCKED);
+       ks_hash_read_unlock(bc->authorizations);
+
+       return authorized;
+}
+
+KS_DECLARE(ks_status_t) blade_channel_authorization_add(blade_channel_t *bc, const char *target)
+{
+       ks_assert(bc);
+       ks_assert(target);
+
+       ks_hash_insert(bc->authorizations, (void *)ks_pstrdup(ks_pool_get(bc), target), (void *)KS_TRUE);
+
+       return KS_STATUS_SUCCESS;
+}
+
+KS_DECLARE(ks_bool_t) blade_channel_authorization_remove(blade_channel_t *bc, const char *target)
+{
+       ks_bool_t ret = KS_FALSE;
+
+       ks_assert(bc);
+       ks_assert(target);
+
+       if (ks_hash_remove(bc->authorizations, (void *)target)) {
+               ret = KS_TRUE;
+       }
+
+       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 9693806b57693961bbdeb7ed007a92ccae14acfe..61337c98e8acee8db5e782d1bcef5c6b462ee5ff 100644 (file)
 struct blade_mastermgr_s {
        blade_handle_t *handle;
 
+       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 *protocols; // protocols that have been published with blade.publish, and the details to locate a protocol controller with blade.locate
+       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
 };
 
 
@@ -70,8 +72,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->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_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_pool_set_cleanup(bmmgr, NULL, blade_mastermgr_cleanup);
 
@@ -105,6 +107,78 @@ KS_DECLARE(blade_handle_t *) blade_mastermgr_handle_get(blade_mastermgr_t *bmmgr
        return bmmgr->handle;
 }
 
+ks_status_t blade_mastermgr_config(blade_mastermgr_t *bmmgr, config_setting_t *config)
+{
+       ks_pool_t *pool = NULL;
+       config_setting_t *master = NULL;
+       config_setting_t *master_nodeid = NULL;
+       const char *nodeid = NULL;
+
+       ks_assert(bmmgr);
+
+       pool = ks_pool_get(bmmgr);
+
+       if (!config_setting_is_group(config)) {
+               ks_log(KS_LOG_DEBUG, "!config_setting_is_group(config)\n");
+               return KS_STATUS_FAIL;
+       }
+
+       master = config_setting_get_member(config, "master");
+       if (master) {
+               master_nodeid = config_lookup_from(master, "nodeid");
+               if (!master_nodeid) return KS_STATUS_FAIL;
+
+               if (config_setting_type(master_nodeid) != CONFIG_TYPE_STRING) return KS_STATUS_FAIL;
+               nodeid = config_setting_get_string(master_nodeid);
+       }
+
+       if (master) {
+               bmmgr->master_nodeid = ks_pstrdup(pool, nodeid);
+
+               ks_log(KS_LOG_DEBUG, "Configured\n");
+       }
+       return KS_STATUS_SUCCESS;
+}
+
+KS_DECLARE(ks_status_t) blade_mastermgr_startup(blade_mastermgr_t *bmmgr, config_setting_t *config)
+{
+       ks_pool_t *pool = NULL;
+
+       ks_assert(bmmgr);
+
+       pool = ks_pool_get(bmmgr);
+
+       if (blade_mastermgr_config(bmmgr, config) != KS_STATUS_SUCCESS) {
+               ks_log(KS_LOG_DEBUG, "blade_mastermgr_config failed\n");
+               return KS_STATUS_FAIL;
+       }
+
+       if (bmmgr->master_nodeid) {
+               blade_realm_t *br = NULL;
+
+               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);
+
+               // 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");
+       }
+
+       return KS_STATUS_SUCCESS;
+}
+
+KS_DECLARE(ks_status_t) blade_mastermgr_shutdown(blade_mastermgr_t *bmmgr)
+{
+       ks_assert(bmmgr);
+       return KS_STATUS_SUCCESS;
+}
+
 KS_DECLARE(ks_status_t) blade_mastermgr_purge(blade_mastermgr_t *bmmgr, const char *nodeid)
 {
        ks_pool_t *pool = NULL;
@@ -114,252 +188,383 @@ KS_DECLARE(ks_status_t) blade_mastermgr_purge(blade_mastermgr_t *bmmgr, const ch
 
        pool = ks_pool_get(bmmgr);
 
-       ks_hash_write_lock(bmmgr->protocols);
-       for (ks_hash_iterator_t *it = ks_hash_first(bmmgr->protocols, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
-               const char *key = NULL;
-               blade_protocol_t *bp = NULL;
+       ks_hash_write_lock(bmmgr->realms);
 
-               ks_hash_this(it, (const void **)&key, NULL, (void **)&bp);
+       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);
 
-               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 *)key, bp);
-                       } else {
-                               // @todo not the last controller, may need to propagate that the controller is no longer available?
+               blade_realm_write_lock(br);
+
+               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(it2, (const void **)&protocol, NULL, (void **)&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 (cleanup) {
-               for (ks_hash_iterator_t *it = ks_hash_first(cleanup, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
-                       const char *key = NULL;
-                       blade_protocol_t *bp = NULL;
 
-                       ks_hash_this(it, (const void **)&key, NULL, (void **)&bp);
+               if (cleanup) {
+                       for (ks_hash_iterator_t *it2 = ks_hash_first(cleanup, KS_UNLOCKED); it2; it2 = ks_hash_next(&it2)) {
+                               const char *protocol = NULL;
+                               blade_protocol_t *bp = NULL;
+
+                               ks_hash_this(it2, (const void **)&protocol, NULL, (void **)&bp);
 
-                       blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE, NULL, blade_protocol_name_get(bp), blade_protocol_realm_get(bp), NULL, NULL, NULL, NULL, NULL);
+                               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\n", key);
-                       ks_hash_remove(bmmgr->protocols, (void *)key);
+                               ks_log(KS_LOG_DEBUG, "Protocol Removed: %s@%s\n", protocol, realm);
+                               blade_protocol_write_unlock(bp);
+                               blade_realm_protocol_remove(br, protocol);
+                       }
+                       ks_hash_destroy(&cleanup);
                }
-               ks_hash_destroy(&cleanup);
+
+               blade_realm_write_unlock(br);
        }
 
-       ks_hash_write_unlock(bmmgr->protocols);
+       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);
 
        return KS_STATUS_SUCCESS;
 }
 
-KS_DECLARE(blade_protocol_t *) blade_mastermgr_protocol_lookup(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm)
+KS_DECLARE(ks_bool_t) blade_mastermgr_realm_remove(blade_mastermgr_t *bmmgr, const char *realm)
+{
+       ks_bool_t ret = KS_FALSE;
+
+       ks_assert(bmmgr);
+       ks_assert(realm);
+
+       if (ks_hash_remove(bmmgr->realms, (void *)realm)) {
+               ret = KS_TRUE;
+               ks_log(KS_LOG_DEBUG, "Realm Removed: %s\n", realm);
+       }
+
+       return ret;
+}
+
+KS_DECLARE(blade_protocol_t *) blade_mastermgr_realm_protocol_lookup(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, ks_bool_t writelocked)
 {
+       blade_realm_t *br = NULL;
        blade_protocol_t *bp = NULL;
-       char *key = NULL;
 
        ks_assert(bmmgr);
        ks_assert(protocol);
        ks_assert(realm);
 
-       key = ks_psprintf(ks_pool_get(bmmgr), "%s@%s", protocol, realm);
-
-       bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)key, KS_READLOCKED);
-       // @todo if (bp) blade_protocol_read_lock(bp);
-       ks_hash_read_unlock(bmmgr->protocols);
+       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);
 
        return bp;
 }
 
-KS_DECLARE(ks_status_t) blade_mastermgr_controller_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, const char *controller)
+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_status_t ret = KS_STATUS_SUCCESS;
        ks_pool_t *pool = NULL;
+       blade_realm_t *br = NULL;
        blade_protocol_t *bp = NULL;
-       char *key = NULL;
 
        ks_assert(bmmgr);
-       ks_assert(protocol);
        ks_assert(realm);
+       ks_assert(protocol);
        ks_assert(controller);
 
        pool = ks_pool_get(bmmgr);
 
-       key = ks_psprintf(pool, "%s@%s", protocol, realm);
+       ks_hash_read_lock(bmmgr->realms);
 
-       ks_hash_write_lock(bmmgr->protocols);
+       br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
+       if (!br) {
+               ret = KS_STATUS_FAIL;
+               goto done;
+       }
 
-       bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)key, KS_UNLOCKED);
+       bp = blade_realm_protocol_lookup(br, protocol, KS_TRUE);
        if (bp) {
                // @todo deal with exclusive stuff when the protocol is already registered
        }
 
        if (!bp) {
-               blade_protocol_create(&bp, pool, protocol, realm);
+               blade_protocol_create(&bp, pool, br, protocol);
                ks_assert(bp);
 
-               ks_log(KS_LOG_DEBUG, "Protocol Added: %s\n", key);
-               ks_hash_insert(bmmgr->protocols, (void *)ks_pstrdup(pool, key), bp);
+               blade_protocol_write_lock(bp);
+
+               ks_log(KS_LOG_DEBUG, "Protocol Added: %s@%s\n", protocol, realm);
+               blade_realm_protocol_add(br, bp);
        }
 
        blade_protocol_controller_add(bp, controller);
 
-       ks_hash_write_unlock(bmmgr->protocols);
+       blade_protocol_write_unlock(bp);
 
-       ks_pool_free(&key);
+done:
+       ks_hash_read_unlock(bmmgr->realms);
 
-       return KS_STATUS_SUCCESS;
+       return ret;
 }
 
-KS_DECLARE(ks_status_t) blade_mastermgr_controller_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, 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_status_t ret = KS_STATUS_SUCCESS;
        ks_pool_t *pool = NULL;
+       blade_realm_t *br = NULL;
        blade_protocol_t *bp = NULL;
-       char *key = NULL;
 
        ks_assert(bmmgr);
-       ks_assert(protocol);
        ks_assert(realm);
+       ks_assert(protocol);
        ks_assert(controller);
 
        pool = ks_pool_get(bmmgr);
 
-       key = ks_psprintf(pool, "%s@%s", protocol, realm);
+       ks_hash_read_lock(bmmgr->realms);
 
-       ks_hash_write_lock(bmmgr->protocols);
+       br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
+       if (!br) {
+               ret = KS_STATUS_FAIL;
+               goto done;
+       }
 
-       bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)key, KS_UNLOCKED);
+       bp = blade_realm_protocol_lookup(br, protocol, KS_TRUE);
        if (bp) {
                if (blade_protocol_controller_remove(bp, controller)) {
                        if (!blade_protocol_controller_available(bp)) {
-                               // @todo broadcast protocol removal to remove all channel subscriptions
-                               ks_log(KS_LOG_DEBUG, "Protocol Removed: %s\n", key);
-                               ks_hash_remove(bmmgr->protocols, (void *)key);
+                               blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_PROTOCOL_REMOVE, NULL, protocol, realm, NULL, NULL, NULL, NULL, NULL);
+
+                               ks_log(KS_LOG_DEBUG, "Protocol Removed: %s@%s\n", protocol, realm);
+                               blade_realm_protocol_remove(br, protocol);
                        } else {
                                // @todo not the last controller, may need to propagate when a specific controller becomes unavailable though
                        }
                }
+               blade_protocol_write_unlock(bp);
        }
 
-       ks_hash_write_unlock(bmmgr->protocols);
-
-       ks_pool_free(&key);
+done:
+       ks_hash_read_unlock(bmmgr->realms);
 
-       return KS_STATUS_SUCCESS;
+       return ret;
 }
 
-KS_DECLARE(ks_status_t) blade_mastermgr_channel_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, const char *channel)
+KS_DECLARE(ks_status_t) blade_mastermgr_realm_protocol_channel_add(blade_mastermgr_t *bmmgr, const char *realm, const char *protocol, const char *channel)
 {
        ks_status_t ret = KS_STATUS_SUCCESS;
+       blade_realm_t *br = NULL;
        blade_protocol_t *bp = NULL;
-       char *key = NULL;
+       blade_channel_t *bc = NULL;
 
        ks_assert(bmmgr);
-       ks_assert(protocol);
        ks_assert(realm);
+       ks_assert(protocol);
        ks_assert(channel);
 
-       key = ks_psprintf(ks_pool_get(bmmgr), "%s@%s", protocol, realm);
+       ks_hash_read_lock(bmmgr->realms);
 
-       bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)key, KS_READLOCKED);
+       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) {
                ret = KS_STATUS_NOT_FOUND;
                goto done;
        }
 
-       blade_protocol_channel_add(bp, channel);
+       bc = blade_protocol_channel_lookup(bp, channel, KS_TRUE);
+       if (!bc) {
+               ret = KS_STATUS_DUPLICATE_OPERATION;
+               goto done;
+       }
 
-done:
-       ks_pool_free(&key);
+       blade_channel_create(&bc, ks_pool_get(bc), channel);
+       ks_assert(bc);
 
-       ks_hash_read_unlock(bmmgr->protocols);
+       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));
+       }
+
+done:
+       if (bc) blade_channel_write_unlock(bc);
+       if (bp) blade_protocol_write_unlock(bp);
+       ks_hash_read_unlock(bmmgr->realms);
 
        return ret;
 }
 
-KS_DECLARE(ks_status_t) blade_mastermgr_channel_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, 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_status_t ret = KS_STATUS_SUCCESS;
+       blade_realm_t *br = NULL;
        blade_protocol_t *bp = NULL;
-       char *key = NULL;
+       blade_channel_t *bc = NULL;
 
        ks_assert(bmmgr);
-       ks_assert(protocol);
        ks_assert(realm);
+       ks_assert(protocol);
        ks_assert(channel);
 
-       key = ks_psprintf(ks_pool_get(bmmgr), "%s@%s", protocol, realm);
+       ks_hash_read_lock(bmmgr->realms);
+
+       br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
+       if (!br) {
+               ret = KS_STATUS_FAIL;
+               goto done;
+       }
 
-       bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)key, KS_READLOCKED);
+       bp = blade_realm_protocol_lookup(br, protocol, KS_TRUE);
        if (!bp) {
                ret = KS_STATUS_NOT_FOUND;
                goto done;
        }
 
+       bc = blade_protocol_channel_lookup(bp, channel, KS_TRUE);
+       if (!bc) {
+               ret = KS_STATUS_NOT_FOUND;
+               goto done;
+       }
+
        if (blade_protocol_channel_remove(bp, channel)) {
-               blade_subscriptionmgr_broadcast(blade_handle_subscriptionmgr_get(bmmgr->handle), BLADE_RPCBROADCAST_COMMAND_CHANNEL_REMOVE, NULL, blade_protocol_name_get(bp), blade_protocol_realm_get(bp), channel, NULL, NULL, NULL, NULL);
+               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_channel_write_unlock(bc);
+               blade_channel_destroy(&bc);
        }
 
 done:
-       ks_pool_free(&key);
-
-       ks_hash_read_unlock(bmmgr->protocols);
+       if (bp) blade_protocol_write_unlock(bp);
+       ks_hash_read_unlock(bmmgr->realms);
 
        return ret;
 }
 
-KS_DECLARE(ks_status_t) blade_mastermgr_channel_authorize(blade_mastermgr_t *bmmgr, ks_bool_t remove, const char *protocol, const char *realm, const char *channel, const char *controller, const char *target)
+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_status_t ret = KS_STATUS_SUCCESS;
+       blade_realm_t *br = NULL;
        blade_protocol_t *bp = NULL;
-       char *key = NULL;
-       //ks_hash_t *cleanup = NULL;
+       blade_channel_t *bc = NULL;
 
        ks_assert(bmmgr);
-       ks_assert(protocol);
        ks_assert(realm);
+       ks_assert(protocol);
        ks_assert(channel);
        ks_assert(controller);
        ks_assert(target);
 
-       key = ks_psprintf(ks_pool_get(bmmgr), "%s@%s", protocol, realm);
+       ks_hash_read_lock(bmmgr->realms);
+
+       br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
+       if (!br) {
+               ret = KS_STATUS_FAIL;
+               goto done;
+       }
 
-       bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)key, KS_READLOCKED);
+       bp = blade_realm_protocol_lookup(br, protocol, KS_FALSE);
        if (!bp) {
                ret = KS_STATUS_NOT_FOUND;
                goto done;
        }
 
-       ret = blade_protocol_channel_authorize(bp, remove, channel, controller, target);
+       if (!blade_protocol_controller_verify(bp, controller)) {
+               ret = KS_STATUS_NOT_ALLOWED;
+               goto done;
+       }
 
-done:
-       ks_pool_free(&key);
+       bc = blade_protocol_channel_lookup(bp, channel, KS_TRUE);
+       if (!bc) {
+               ret = KS_STATUS_NOT_FOUND;
+               goto done;
+       }
 
-       ks_hash_read_unlock(bmmgr->protocols);
+       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));
+               } 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));
+               }
+       }
+
+done:
+       if (bc) blade_channel_write_unlock(bc);
+       if (bp) blade_protocol_read_unlock(bp);
+       ks_hash_read_unlock(bmmgr->realms);
 
        return ret;
 }
 
-KS_DECLARE(ks_bool_t) blade_mastermgr_channel_verify(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, const char *channel, 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_bool_t ret = KS_FALSE;
+       blade_realm_t *br = NULL;
        blade_protocol_t *bp = NULL;
-       char *key = NULL;
-       //ks_hash_t *cleanup = NULL;
+       blade_channel_t *bc = NULL;
 
        ks_assert(bmmgr);
-       ks_assert(protocol);
        ks_assert(realm);
+       ks_assert(protocol);
        ks_assert(channel);
        ks_assert(target);
 
-       key = ks_psprintf(ks_pool_get(bmmgr), "%s@%s", protocol, realm);
+       ks_hash_read_lock(bmmgr->realms);
 
-       bp = (blade_protocol_t *)ks_hash_search(bmmgr->protocols, (void *)key, KS_READLOCKED);
-       if (!bp) goto done;
+       br = (blade_realm_t *)ks_hash_search(bmmgr->realms, (void *)realm, KS_UNLOCKED);
+       if (!br) {
+               ret = KS_STATUS_FAIL;
+               goto done;
+       }
 
-       ret = blade_protocol_channel_verify(bp, channel, target);
+       bp = blade_realm_protocol_lookup(br, protocol, KS_FALSE);
+       if (!bp) {
+               ret = KS_STATUS_NOT_FOUND;
+               goto done;
+       }
 
-done:
-       ks_pool_free(&key);
+       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);
 
-       ks_hash_read_unlock(bmmgr->protocols);
+       blade_protocol_read_unlock(bp);
+
+done:
+       if (bc) blade_channel_read_unlock(bc);
+       if (bp) blade_protocol_read_unlock(bp);
+       ks_hash_read_unlock(bmmgr->realms);
 
        return ret;
 }
diff --git a/libs/libblade/src/blade_module_master.c b/libs/libblade/src/blade_module_master.c
deleted file mode 100644 (file)
index fc3163e..0000000
+++ /dev/null
@@ -1,274 +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"
-
-typedef struct blade_module_master_s blade_module_master_t;
-
-struct blade_module_master_s {
-       blade_handle_t *handle;
-       ks_pool_t *pool;
-       blade_module_t *module;
-
-       blade_space_t *blade_space;
-       blade_space_t *blade_application_space;
-};
-
-
-ks_bool_t blade_register_request_handler(blade_module_t *bm, blade_request_t *breq);
-// @todo blade_unregister_request_handler for more graceful shutdowns which intend to disconnect, and won't reconnect, which expire a session immediately
-ks_bool_t blade_application_register_request_handler(blade_module_t *bm, blade_request_t *breq); // @todo response of registration indicates if you are the primary, or a slave
-// @todo blade_application_unregister_request_handler for ability to unregister a slave (or primary) from the application, upon last node unregistering, the application entry would be automatically destroyed
-// @todo event (or request to confirm acceptance with a response?) that allows a master to tell a slave it's the new primary for an application it has registered to provide when a primary disconnects, or a
-// primary change is requested externally
-// @todo to avoid a race condition, if a slave gets unexpected primary calls before being notified by an event, should it assume it has become the primary and not yet notified?
-
-static blade_module_callbacks_t g_module_master_callbacks =
-{
-       blade_module_master_on_startup,
-       blade_module_master_on_shutdown,
-};
-
-
-static void blade_module_master_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
-{
-       //blade_module_master_t *bm_master = (blade_module_master_t *)ptr;
-
-       //ks_assert(bm_master);
-
-       switch (action) {
-       case KS_MPCL_ANNOUNCE:
-               break;
-       case KS_MPCL_TEARDOWN:
-               break;
-       case KS_MPCL_DESTROY:
-               break;
-       }
-}
-
-KS_DECLARE(ks_status_t) blade_module_master_create(blade_module_t **bmP, blade_handle_t *bh)
-{
-       blade_module_master_t *bm_master = NULL;
-       ks_pool_t *pool = NULL;
-
-       ks_assert(bmP);
-       ks_assert(bh);
-
-       ks_pool_open(&pool);
-       ks_assert(pool);
-
-    bm_master = ks_pool_alloc(pool, sizeof(blade_module_master_t));
-       bm_master->handle = bh;
-       bm_master->pool = pool;
-
-       blade_module_create(&bm_master->module, bh, pool, bm_master, &g_module_master_callbacks);
-
-       ks_pool_set_cleanup(pool, bm_master, NULL, blade_module_master_cleanup);
-
-       ks_log(KS_LOG_DEBUG, "Created\n");
-
-       *bmP = bm_master->module;
-
-       return KS_STATUS_SUCCESS;
-}
-
-
-ks_status_t blade_module_master_config(blade_module_master_t *bm_master, config_setting_t *config)
-{
-       ks_assert(bm_master);
-       ks_assert(config);
-
-       ks_log(KS_LOG_DEBUG, "Configured\n");
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_module_master_on_startup(blade_module_t *bm, config_setting_t *config)
-{
-       blade_module_master_t *bm_master = NULL;
-       blade_space_t *space = NULL;
-       blade_method_t *method = NULL;
-
-       ks_assert(bm);
-       ks_assert(config);
-
-       bm_master = (blade_module_master_t *)blade_module_data_get(bm);
-
-    if (blade_module_master_config(bm_master, config) != KS_STATUS_SUCCESS) {
-               ks_log(KS_LOG_DEBUG, "blade_module_master_config failed\n");
-               return KS_STATUS_FAIL;
-       }
-
-       blade_space_create(&space, bm_master->handle, bm, "blade");
-       ks_assert(space);
-
-       bm_master->blade_space = space;
-
-       blade_method_create(&method, space, "register", blade_register_request_handler);
-       ks_assert(method);
-       blade_space_methods_add(space, method);
-
-       blade_handle_space_register(space);
-
-
-       blade_space_create(&space, bm_master->handle, bm, "blade.application");
-       ks_assert(space);
-
-       bm_master->blade_application_space = space;
-
-       blade_method_create(&method, space, "register", blade_application_register_request_handler);
-       ks_assert(method);
-       blade_space_methods_add(space, method);
-
-       blade_handle_space_register(space);
-
-
-       ks_log(KS_LOG_DEBUG, "Started\n");
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_module_master_on_shutdown(blade_module_t *bm)
-{
-       blade_module_master_t *bm_master = NULL;
-
-       ks_assert(bm);
-
-       bm_master = (blade_module_master_t *)blade_module_data_get(bm);
-
-       if (bm_master->blade_application_space) blade_handle_space_unregister(bm_master->blade_application_space);
-       if (bm_master->blade_space) blade_handle_space_unregister(bm_master->blade_space);
-
-       ks_log(KS_LOG_DEBUG, "Stopped\n");
-
-       return KS_STATUS_SUCCESS;
-}
-
-ks_bool_t blade_register_request_handler(blade_module_t *bm, blade_request_t *breq)
-{
-       blade_module_master_t *bm_master = NULL;
-       blade_session_t *bs = NULL;
-       cJSON *params = NULL;
-       cJSON *res = NULL;
-       const char *params_identity = NULL;
-       const char *identity = NULL;
-
-       ks_assert(bm);
-       ks_assert(breq);
-
-       ks_log(KS_LOG_DEBUG, "Request Received!\n");
-
-       bm_master = (blade_module_master_t *)blade_module_data_get(bm);
-       ks_assert(bm_master);
-
-       bs = blade_handle_sessions_get(breq->handle, breq->session_id);
-       ks_assert(bs);
-
-       blade_session_properties_write_lock(bs, KS_TRUE);
-
-       params = cJSON_GetObjectItem(breq->message, "params"); // @todo cache this in blade_request_t for quicker/easier access
-       if (!params) {
-               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to register with no 'params' object\n", blade_session_id_get(bs));
-               blade_rpc_error_create(&res, NULL, breq->message_id, -32602, "Missing params object");
-       }
-       else if (!(params_identity = cJSON_GetObjectCstr(params, "identity"))) {
-               ks_log(KS_LOG_DEBUG, "Session (%s) attempted to register with no 'identity'\n", blade_session_id_get(bs));
-               blade_rpc_error_create(&res, NULL, breq->message_id, -32602, "Missing params identity string");
-       } else {
-               identity = blade_session_identity_get(bs);
-               if (identity && identity[0]) {
-                       ks_log(KS_LOG_DEBUG, "Session (%s) attempted to register with master but is already registered as %s\n", blade_session_id_get(bs), identity);
-                       blade_rpc_error_create(&res, NULL, breq->message_id, -1000, "Already registered");
-               } else {
-                       // @todo plug in authentication to confirm if this registration is permitted, just allow it for now as long as it's not already in use
-
-                       blade_rpc_response_create(&res, NULL, breq->message_id);
-
-                       // @todo this is completely unfinished, return to finish this after catching up other changes
-                       //blade_handle_session_identify(bh, identity, bs);
-                       //blade_session_identity_set(bs, params_identity);
-               }
-       }
-
-       blade_session_properties_write_unlock(bs);
-
-       blade_session_send(bs, res, NULL);
-
-       blade_session_read_unlock(bs);
-
-       cJSON_Delete(res);
-
-       return KS_FALSE;
-}
-
-ks_bool_t blade_application_register_request_handler(blade_module_t *bm, blade_request_t *breq)
-{
-       blade_module_master_t *bm_master = NULL;
-       blade_session_t *bs = NULL;
-       //cJSON *res = NULL;
-
-       ks_assert(bm);
-       ks_assert(breq);
-
-       ks_log(KS_LOG_DEBUG, "Request Received!\n");
-
-       bm_master = (blade_module_master_t *)blade_module_data_get(bm);
-       ks_assert(bm_master);
-
-       bs = blade_handle_sessions_get(breq->handle, breq->session_id);
-       ks_assert(bs);
-
-       //blade_rpc_error_create(&res, NULL, breq->message_id, -10000, "???");
-       //blade_rpc_response_create(&res, NULL, breq->message_id);
-
-
-       //blade_session_send(bs, res, NULL);
-
-       blade_session_read_unlock(bs);
-
-       //cJSON_Delete(res);
-
-       return KS_FALSE;
-}
-
-
-/* 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 e3de68a77f57b6ed3c1885242c0ceb0d22950315..79efbf1895fed5dbec371187ba2a62427cb51ea2 100644 (file)
@@ -34,8 +34,9 @@
 #include "blade.h"
 
 struct blade_protocol_s {
+       blade_realm_t *realm;
        const char *name;
-       const char *realm;
+       ks_rwl_t *lock;
        ks_hash_t *controllers;
        ks_hash_t *channels;
        // @todo descriptors (schema, etc) for each method within a protocol
@@ -53,7 +54,7 @@ static void blade_protocol_cleanup(void *ptr, void *arg, ks_pool_cleanup_action_
                break;
        case KS_MPCL_TEARDOWN:
                if (bp->name) ks_pool_free(&bp->name);
-               if (bp->realm) ks_pool_free(&bp->realm);
+               if (bp->lock) ks_rwl_destroy(&bp->lock);
                if (bp->controllers) ks_hash_destroy(&bp->controllers);
                if (bp->channels) ks_hash_destroy(&bp->channels);
                break;
@@ -62,18 +63,21 @@ 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, const char *name, const char *realm)
+KS_DECLARE(ks_status_t) blade_protocol_create(blade_protocol_t **bpP, ks_pool_t *pool, blade_realm_t *realm, const char *name)
 {
        blade_protocol_t *bp = NULL;
 
        ks_assert(bpP);
        ks_assert(pool);
-       ks_assert(name);
        ks_assert(realm);
+       ks_assert(name);
 
        bp = ks_pool_alloc(pool, sizeof(blade_protocol_t));
+       bp->realm = realm;
        bp->name = ks_pstrdup(pool, name);
-       bp->realm = ks_pstrdup(pool, realm);
+
+       ks_rwl_create(&bp->lock, pool);
+       ks_assert(bp->lock);
 
        ks_hash_create(&bp->controllers, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
        ks_assert(bp->controllers);
@@ -98,16 +102,40 @@ 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);
        return bp->name;
 }
 
-KS_DECLARE(const char *) blade_protocol_realm_get(blade_protocol_t *bp)
+KS_DECLARE(ks_status_t) blade_protocol_read_lock(blade_protocol_t *bp)
 {
        ks_assert(bp);
-       return bp->realm;
+       return ks_rwl_read_lock(bp->lock);
+}
+
+KS_DECLARE(ks_status_t) blade_protocol_read_unlock(blade_protocol_t *bp)
+{
+       ks_assert(bp);
+       return ks_rwl_read_unlock(bp->lock);
+}
+
+KS_DECLARE(ks_status_t) blade_protocol_write_lock(blade_protocol_t *bp)
+{
+       ks_assert(bp);
+       return ks_rwl_write_lock(bp->lock);
+}
+
+KS_DECLARE(ks_status_t) blade_protocol_write_unlock(blade_protocol_t *bp)
+{
+       ks_assert(bp);
+       return ks_rwl_write_unlock(bp->lock);
 }
 
 KS_DECLARE(ks_bool_t) blade_protocol_purge(blade_protocol_t *bp, const char *nodeid)
@@ -124,7 +152,7 @@ KS_DECLARE(ks_bool_t) blade_protocol_purge(blade_protocol_t *bp, const char *nod
                ks_hash_this(it, (const void **)&key, NULL, (void **)&authorizations);
 
                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, bp->realm, key);
+                       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);
                }
        }
        ks_hash_write_unlock(bp->channels);
@@ -152,6 +180,19 @@ KS_DECLARE(cJSON *) blade_protocol_controller_pack(blade_protocol_t *bp)
        return controllers;
 }
 
+KS_DECLARE(ks_bool_t) blade_protocol_controller_verify(blade_protocol_t *bp, const char *controller)
+{
+       ks_bool_t ret = KS_FALSE;
+
+       ks_assert(bp);
+       ks_assert(controller);
+
+       ret = (ks_bool_t)(uintptr_t)ks_hash_search(bp->controllers, controller, KS_READLOCKED);
+       ks_hash_read_unlock(bp->controllers);
+
+       return ret;
+}
+
 KS_DECLARE(ks_status_t) blade_protocol_controller_add(blade_protocol_t *bp, const char *nodeid)
 {
        char *key = NULL;
@@ -162,7 +203,7 @@ 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, bp->realm);
+       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;
 }
@@ -177,7 +218,7 @@ 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, bp->realm);
+               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);
 
@@ -190,112 +231,57 @@ KS_DECLARE(ks_bool_t) blade_protocol_controller_available(blade_protocol_t *bp)
        return ks_hash_count(bp->controllers) > 0;
 }
 
-KS_DECLARE(ks_status_t) blade_protocol_channel_add(blade_protocol_t *bp, const char *name)
-{
-       ks_status_t ret = KS_STATUS_SUCCESS;
-       ks_pool_t *pool = NULL;
-       ks_hash_t *authorized = NULL;
-       char *key = NULL;
-
-       ks_assert(bp);
-       ks_assert(name);
-
-       pool = ks_pool_get(bp);
-
-       ks_hash_write_lock(bp->channels);
-
-       if (ks_hash_search(bp->channels, (void *)name, KS_UNLOCKED)) {
-               ret = KS_STATUS_DUPLICATE_OPERATION;
-               goto done;
-       }
-
-       ks_hash_create(&authorized, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
-
-       key = ks_pstrdup(pool, name);
-       ks_hash_insert(bp->channels, (void *)key, (void *)authorized);
-
-       ks_log(KS_LOG_DEBUG, "Protocol Channel Added: %s to %s@%s\n", key, bp->name, bp->realm);
-
-done:
-
-       ks_hash_write_unlock(bp->channels);
-
-       return ret;
-}
-
-KS_DECLARE(ks_bool_t) blade_protocol_channel_remove(blade_protocol_t *bp, const char *name)
+KS_DECLARE(blade_channel_t *) blade_protocol_channel_lookup(blade_protocol_t *bp, const char *channel, ks_bool_t writelocked)
 {
-       ks_bool_t ret = KS_FALSE;
-       ks_hash_t *authorized = NULL;
+       blade_channel_t *bc = NULL;
 
        ks_assert(bp);
-       ks_assert(name);
+       ks_assert(channel);
 
-       ks_hash_write_lock(bp->channels);
-       if ((authorized = ks_hash_remove(bp->channels, (void *)name))) {
-               ret = KS_TRUE;
-               ks_log(KS_LOG_DEBUG, "Protocol Channel Removed: %s from %s@%s\n", name, bp->name, bp->realm);
-               ks_hash_destroy(&authorized);
+       bc = (blade_channel_t *)ks_hash_search(bp->channels, (void *)channel, KS_READLOCKED);
+       if (bc) {
+               if (writelocked) blade_channel_write_lock(bc);
+               else blade_channel_read_lock(bc);
        }
-       ks_hash_write_unlock(bp->channels);
+       ks_hash_read_unlock(bp->channels);
 
-       return ret;
+       return bc;
 }
 
-KS_DECLARE(ks_status_t) blade_protocol_channel_authorize(blade_protocol_t *bp, ks_bool_t remove, const char *channel, const char *controller, const char *target)
+KS_DECLARE(ks_status_t) blade_protocol_channel_add(blade_protocol_t *bp, blade_channel_t *channel)
 {
        ks_status_t ret = KS_STATUS_SUCCESS;
-       ks_hash_t *authorizations = NULL;
-       ks_bool_t allowed = KS_FALSE;
+       ks_pool_t *pool = NULL;
+       char *key = NULL;
 
        ks_assert(bp);
        ks_assert(channel);
-       ks_assert(controller);
-       ks_assert(target);
 
-       allowed = (ks_bool_t)(intptr_t)ks_hash_search(bp->controllers, (void *)controller, KS_READLOCKED);
-       ks_hash_read_unlock(bp->controllers);
+       pool = ks_pool_get(bp);
 
-       if (!allowed) {
-               ret = KS_STATUS_NOT_ALLOWED;
-               goto done;
-       }
+       ks_hash_write_lock(bp->channels);
 
-       // @todo verify controller, get ks_hash_t* value based on channel, add target to the channels hash
-       authorizations = (ks_hash_t *)ks_hash_search(bp->channels, (void *)channel, KS_READLOCKED);
-       if (authorizations) {
-               if (remove) {
-                       if (ks_hash_remove(authorizations, (void *)target)) {
-                               ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Removed: %s from %s@%s/%s\n", target, bp->name, bp->realm, channel);
-                       } else ret = KS_STATUS_NOT_FOUND;
-               } else {
-                       ks_hash_insert(authorizations, (void *)ks_pstrdup(ks_pool_get(bp), target), (void *)KS_TRUE);
-                       ks_log(KS_LOG_DEBUG, "Protocol Channel Authorization Added: %s to %s@%s/%s\n", target, bp->name, bp->realm, channel);
-               }
+       if (ks_hash_search(bp->channels, (void *)blade_channel_name_get(channel), KS_UNLOCKED)) {
+               ret = KS_STATUS_DUPLICATE_OPERATION;
+               goto done;
        }
-       ks_hash_read_unlock(bp->channels);
 
-       if (!authorizations) ret = KS_STATUS_NOT_FOUND;
+       key = ks_pstrdup(pool, blade_channel_name_get(channel));
+       ks_hash_insert(bp->channels, (void *)key, (void *)channel);
 
 done:
+
+       ks_hash_write_unlock(bp->channels);
+
        return ret;
 }
 
-KS_DECLARE(ks_bool_t) blade_protocol_channel_verify(blade_protocol_t *bp, const char *channel, const char *target)
+KS_DECLARE(ks_bool_t) blade_protocol_channel_remove(blade_protocol_t *bp, const char *channel)
 {
-       ks_bool_t ret = KS_FALSE;
-       ks_hash_t *authorizations = NULL;
-
        ks_assert(bp);
        ks_assert(channel);
-       ks_assert(target);
 
-       // @todo verify controller, get ks_hash_t* value based on channel, add target to the channels hash
-       authorizations = (ks_hash_t *)ks_hash_search(bp->channels, (void *)channel, KS_READLOCKED);
-       if (authorizations) ret = ks_hash_search(authorizations, (void *)target, KS_UNLOCKED) != NULL;
-       ks_hash_read_unlock(bp->channels);
-
-       return ret;
+       return ks_hash_remove(bp->channels, (void *)channel) != NULL;
 }
 
 /* For Emacs:
diff --git a/libs/libblade/src/blade_realm.c b/libs/libblade/src/blade_realm.c
new file mode 100644 (file)
index 0000000..149b57e
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * 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 5aceafd18beddca98668573d05408f24db47a5e3..277908a5998b33e7950a1b2da2543ac8b8fc45e4 100644 (file)
@@ -141,6 +141,13 @@ KS_DECLARE(ks_status_t) blade_routemgr_route_add(blade_routemgr_t *brmgr, const
 
        blade_handle_rpcregister(brmgr->handle, target, KS_FALSE, NULL, NULL);
 
+       if (blade_upstreammgr_masterlocal(blade_handle_upstreammgr_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, "presence", "blade", "join", "joined", params, NULL, NULL);
+               cJSON_Delete(params);
+       }
+
        return KS_STATUS_SUCCESS;
 
 }
@@ -165,6 +172,13 @@ 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))) {
+               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);
+               cJSON_Delete(params);
+       }
+
        return KS_STATUS_SUCCESS;
 }
 
index 700c66bab0612ee6773ee2c064f6015b70a9be1e..462c4713a4a25c67ecc6088618885bcc94fb8a8b 100644 (file)
@@ -49,7 +49,6 @@ struct blade_session_s {
        ks_q_t *sending;
        ks_q_t *receiving;
 
-       ks_hash_t *realms;
        ks_hash_t *routes;
 
        cJSON *properties;
@@ -115,9 +114,6 @@ KS_DECLARE(ks_status_t) blade_session_create(blade_session_t **bsP, blade_handle
        ks_q_create(&bs->receiving, pool, 0);
        ks_assert(bs->receiving);
 
-       ks_hash_create(&bs->realms, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
-       ks_assert(bs->realms);
-
        ks_hash_create(&bs->routes, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
        ks_assert(bs->routes);
 
@@ -225,35 +221,6 @@ KS_DECLARE(blade_session_state_t) blade_session_state_get(blade_session_t *bs)
        return bs->state;
 }
 
-KS_DECLARE(ks_status_t) blade_session_realm_add(blade_session_t *bs, const char *realm)
-{
-       char *key = NULL;
-
-       ks_assert(bs);
-       ks_assert(realm);
-
-       key = ks_pstrdup(ks_pool_get(bs), realm);
-       ks_hash_insert(bs->realms, (void *)key, (void *)KS_TRUE);
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_session_realm_remove(blade_session_t *bs, const char *realm)
-{
-       ks_assert(bs);
-       ks_assert(realm);
-
-       ks_hash_remove(bs->realms, (void *)realm);
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_hash_t *) blade_session_realms_get(blade_session_t *bs)
-{
-       ks_assert(bs);
-       return bs->realms;
-}
-
 KS_DECLARE(ks_status_t) blade_session_route_add(blade_session_t *bs, const char *nodeid)
 {
        char *key = NULL;
index e231b2eb1ecfcb7cdd7b9cab3aab1b0bd797cd04..5e13bc69a28575936926bda69e69d8f7b8c832da 100644 (file)
@@ -197,7 +197,6 @@ KS_DECLARE(ks_status_t) blade_sessionmgr_session_remove(blade_sessionmgr_t *bsmg
        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);
-               blade_upstreammgr_realm_clear(blade_handle_upstreammgr_get(bsmgr->handle));
        }
 
        blade_session_write_unlock(bs);
index 315c4f72150717012b9883dd0a85a44e09199534..929c6cb592c37679e8d98d68ad0c48aaabae4d48 100644 (file)
@@ -157,12 +157,6 @@ KS_DECLARE(ks_status_t) blade_handle_destroy(blade_handle_t **bhP)
 
 ks_status_t blade_handle_config(blade_handle_t *bh, config_setting_t *config)
 {
-       config_setting_t *master = NULL;
-       config_setting_t *master_nodeid = NULL;
-       config_setting_t *master_realms = NULL;
-       const char *nodeid = NULL;
-       int32_t realms_length = 0;
-
        ks_assert(bh);
 
        if (!config) return KS_STATUS_FAIL;
@@ -171,30 +165,6 @@ ks_status_t blade_handle_config(blade_handle_t *bh, config_setting_t *config)
                return KS_STATUS_FAIL;
        }
 
-       master = config_setting_get_member(config, "master");
-       if (master) {
-               master_nodeid = config_lookup_from(master, "nodeid");
-               if (master_nodeid) {
-                       if (config_setting_type(master_nodeid) != CONFIG_TYPE_STRING) return KS_STATUS_FAIL;
-                       nodeid = config_setting_get_string(master_nodeid);
-
-                       blade_upstreammgr_localid_set(bh->upstreammgr, nodeid);
-                       blade_upstreammgr_masterid_set(bh->upstreammgr, nodeid);
-               }
-               master_realms = config_lookup_from(master, "realms");
-               if (master_realms) {
-                       if (config_setting_type(master_realms) != CONFIG_TYPE_LIST) return KS_STATUS_FAIL;
-                       realms_length = config_setting_length(master_realms);
-                       if (realms_length > 0) {
-                               for (int32_t index = 0; index < realms_length; ++index) {
-                                       const char *realm = config_setting_get_string_elem(master_realms, index);
-                                       if (!realm) return KS_STATUS_FAIL;
-                                       blade_upstreammgr_realm_add(bh->upstreammgr, realm);
-                               }
-                       }
-               }
-       }
-
        return KS_STATUS_SUCCESS;
 }
 
@@ -242,6 +212,8 @@ KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_
 
        blade_transportmgr_startup(bh->transportmgr, config);
 
+       blade_mastermgr_startup(bh->mastermgr, config);
+
        return KS_STATUS_SUCCESS;
 }
 
@@ -249,6 +221,8 @@ KS_DECLARE(ks_status_t) blade_handle_shutdown(blade_handle_t *bh)
 {
        ks_assert(bh);
 
+       blade_mastermgr_shutdown(bh->mastermgr);
+
        blade_transportmgr_shutdown(bh->transportmgr);
 
        blade_connectionmgr_shutdown(bh->connectionmgr);
@@ -653,22 +627,22 @@ 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_controller_add(bh->mastermgr, req_params_protocol, req_params_realm, req_params_requester_nodeid);
+               blade_mastermgr_realm_protocol_controller_add(bh->mastermgr, req_params_realm, req_params_protocol, req_params_requester_nodeid);
                if (req_params_channels) {
                        cJSON *element = NULL;
                        cJSON_ArrayForEach(element, req_params_channels) {
-                               blade_mastermgr_channel_add(bh->mastermgr, req_params_protocol, req_params_realm, element->valuestring);
+                               blade_mastermgr_realm_protocol_channel_add(bh->mastermgr, req_params_realm, req_params_protocol, element->valuestring);
                        }
                }
                break;
        case BLADE_RPCPUBLISH_COMMAND_CONTROLLER_REMOVE:
-               blade_mastermgr_controller_remove(bh->mastermgr, req_params_protocol, req_params_realm, req_params_requester_nodeid);
+               blade_mastermgr_realm_protocol_controller_remove(bh->mastermgr, req_params_realm, 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_channel_add(bh->mastermgr, req_params_protocol, req_params_realm, element->valuestring);
+                               blade_mastermgr_realm_protocol_channel_add(bh->mastermgr, req_params_realm, req_params_protocol, element->valuestring);
                        }
                }
                break;
@@ -676,7 +650,7 @@ ks_bool_t blade_rpcpublish_request_handler(blade_rpc_request_t *brpcreq, void *d
                if (req_params_channels) {
                        cJSON *element = NULL;
                        cJSON_ArrayForEach(element, req_params_channels) {
-                               blade_mastermgr_channel_remove(bh->mastermgr, req_params_protocol, req_params_realm, element->valuestring);
+                               blade_mastermgr_realm_protocol_channel_remove(bh->mastermgr, req_params_realm, req_params_protocol, element->valuestring);
                        }
                }
                break;
@@ -889,7 +863,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_channel_authorize(bh->mastermgr, remove, req_params_protocol, req_params_realm, channel->valuestring, req_params_requester_nodeid, req_params_authorized_nodeid) == KS_STATUS_SUCCESS) {
+               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 (remove) {
                                if (!res_result_unauthorized_channels) res_result_unauthorized_channels = cJSON_CreateArray();
                                cJSON_AddItemToArray(res_result_unauthorized_channels, cJSON_CreateString(channel->valuestring));
@@ -1060,8 +1034,11 @@ 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_protocol_lookup(bh->mastermgr, req_params_protocol, req_params_realm);
-       if (bp) res_result_controllers = blade_protocol_controller_pack(bp);
+       bp = blade_mastermgr_realm_protocol_lookup(bh->mastermgr, req_params_realm, req_params_protocol, KS_FALSE);
+       if (bp) {
+               res_result_controllers = blade_protocol_controller_pack(bp);
+               blade_protocol_read_unlock(bp);
+       }
 
 
        // build the actual response finally
@@ -1630,7 +1607,7 @@ 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_channel_verify(bh->mastermgr, req_params_protocol, req_params_realm, channel->valuestring, req_params_subscriber_nodeid)) {
+                               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 (!res_result_subscribe_channels) res_result_subscribe_channels = cJSON_CreateArray();
                                        cJSON_AddItemToArray(res_result_subscribe_channels, cJSON_CreateString(channel->valuestring));
@@ -1926,6 +1903,66 @@ 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;
+
+       ks_assert(brpcreq);
+
+       req = blade_rpc_request_message_get(brpcreq);
+       ks_assert(req);
+
+       req_protocol = cJSON_GetObjectCstr(req, "protocol");
+
+       return req_protocol;
+}
+
+KS_DECLARE(const char *) blade_rpcbroadcast_request_channel_get(blade_rpc_request_t *brpcreq)
+{
+       cJSON *req = NULL;
+       const char *req_channel = NULL;
+
+       ks_assert(brpcreq);
+
+       req = blade_rpc_request_message_get(brpcreq);
+       ks_assert(req);
+
+       req_channel = cJSON_GetObjectCstr(req, "channel");
+
+       return req_channel;
+}
+
+KS_DECLARE(const char *) blade_rpcbroadcast_request_event_get(blade_rpc_request_t *brpcreq)
+{
+       cJSON *req = NULL;
+       const char *req_event = NULL;
+
+       ks_assert(brpcreq);
+
+       req = blade_rpc_request_message_get(brpcreq);
+       ks_assert(req);
+
+       req_event = cJSON_GetObjectCstr(req, "event");
+
+       return req_event;
+}
+
 KS_DECLARE(cJSON *) blade_rpcbroadcast_request_params_get(blade_rpc_request_t *brpcreq)
 {
        cJSON *req = NULL;
@@ -1943,6 +1980,7 @@ KS_DECLARE(cJSON *) blade_rpcbroadcast_request_params_get(blade_rpc_request_t *b
        return req_params_params;
 }
 
+
 /* For Emacs:
  * Local Variables:
  * mode:c
index 90fac85dd8b6ec56afe6ab505acc3b637099a12a..db55ca4e441cdd78cfbb38c1bafe2647c32aa596 100644 (file)
@@ -213,6 +213,7 @@ ks_status_t blade_transport_wss_link_ssl_init(blade_transport_wss_link_t *btwssl
        cert = server ? btwssl->transport->endpoints_ssl_cert : btwssl->transport->ssl_cert;
        chain = server ? btwssl->transport->endpoints_ssl_chain : btwssl->transport->ssl_chain;
 
+       // @todo should actually error out if there is no key/cert/chain available, as SSL/TLS is meant to be mandatory
        if (key && cert) {
                btwssl->ssl = SSL_CTX_new(method);
 
@@ -426,7 +427,7 @@ ks_status_t blade_transport_wss_onstartup(blade_transport_t *bt, config_setting_
        btwss = (blade_transport_wss_t *)blade_transport_data_get(bt);
 
     if (blade_transport_wss_config(btwss, config) != KS_STATUS_SUCCESS) {
-               ks_log(KS_LOG_DEBUG, "blade_module_wss_config failed\n");
+               ks_log(KS_LOG_DEBUG, "blade_transport_wss_config failed\n");
                return KS_STATUS_FAIL;
        }
 
@@ -826,7 +827,6 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
        cJSON *json_res = NULL;
        cJSON *json_params = NULL;
        cJSON *json_result = NULL;
-       cJSON *json_result_realms = NULL;
        //cJSON *error = NULL;
        blade_session_t *bs = NULL;
        blade_handle_t *bh = NULL;
@@ -837,8 +837,6 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
        const char *nodeid = NULL;
        const char *master_nodeid = NULL;
        ks_time_t timeout;
-       ks_hash_iterator_t *it = NULL;
-       ks_hash_t *realms = NULL;
 
        ks_assert(bc);
 
@@ -957,11 +955,6 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
                // 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
                blade_routemgr_route_add(blade_handle_routemgr_get(bh), nodeid, nodeid);
-
-               // iterate and copy the realms ultimately provided by the master router node to the new downstream session, realms are obtained when establishing upstream sessions (see outbound handler), in
-               // the future this process can be adjusted based on authentication which is currently skipped, so for now if a master node provides more than a single realm then all provided realms will be
-               // acceptable for protocol publishing and passing to downstream sessions for their realms
-               blade_upstreammgr_realm_propagate(blade_handle_upstreammgr_get(bh), bs);
        }
 
        blade_rpc_response_raw_create(&json_res, &json_result, id);
@@ -982,26 +975,6 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
        cJSON_AddStringToObject(json_result, "master-nodeid", master_nodeid);
        ks_pool_free(&master_nodeid);
 
-
-       // add the list of actual realms the local node will permit the remote node to register or route, this is the same list that the remote side would be adding to the handle with blade_handle_realm_add()
-       // and may contain additional subrealms that are explicitly registered by the remote node, this ensures upon reconnect that the same list of realms gets provided to the remote node to refresh
-       // the remote nodes local realms on the edge case that the session times out on the remote end while reconnecting
-
-       json_result_realms = cJSON_CreateArray();
-       cJSON_AddItemToObject(json_result, "realms", json_result_realms);
-
-       realms = blade_session_realms_get(bs);
-       ks_hash_read_lock(realms);
-       for (it = ks_hash_first(realms, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
-               void *key = NULL;
-               void *value = NULL;
-
-               ks_hash_this(it, (const void **)&key, NULL, &value);
-
-               cJSON_AddItemToArray(json_result_realms, cJSON_CreateString((const char *)key));
-       }
-       ks_hash_read_unlock(realms);
-
        // 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
        // with making sure both this connection and the session state machines are in running states
@@ -1041,8 +1014,6 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_outbound(blade
        const char *id = NULL;
        cJSON *json_error = NULL;
        cJSON *json_result = NULL;
-       cJSON *json_result_realms = NULL;
-       int json_result_realms_size = 0;
        const char *nodeid = NULL;
        const char *master_nodeid = NULL;
        blade_session_t *bs = NULL;
@@ -1141,13 +1112,6 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_outbound(blade
                goto done;
        }
 
-       json_result_realms = cJSON_GetObjectItem(json_result, "realms");
-       if (!json_result_realms || json_result_realms->type != cJSON_Array || (json_result_realms_size = cJSON_GetArraySize(json_result_realms)) <= 0) {
-               ks_log(KS_LOG_DEBUG, "Received message is missing 'realms'\n");
-               ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
-               goto done;
-       }
-
 
        // @todo validate uuid format by parsing, not currently available in uuid functions
        bs = blade_sessionmgr_session_lookup(blade_handle_sessionmgr_get(bh), nodeid); // bs comes out read locked if not null to prevent it being cleaned up before we are done
@@ -1186,12 +1150,6 @@ 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);
-
-               // iterate realms and register to handle as permitted realms for future registrations
-               for (int index = 0; index < json_result_realms_size; ++index) {
-                       cJSON *elem = cJSON_GetArrayItem(json_result_realms, index);
-                       blade_upstreammgr_realm_add(blade_handle_upstreammgr_get(bh), elem->valuestring);
-               }
        }
 
        blade_connection_session_set(bc, blade_session_id_get(bs));
index d7ba4bd9ecde8f0f35747b31b4b440a3eb32f5ce..bcdee57834c49af57e87542e7757145727db2440 100644 (file)
@@ -43,9 +43,6 @@ struct blade_upstreammgr_s {
        // master node id, provided by upstream "blade.connect" response
        const char *masterid;
        ks_rwl_t *masterid_rwl;
-
-       // realms for new nodes, these originate from the master, and are provided by upstream session "blade.connect" response
-       ks_hash_t *realms;
 };
 
 
@@ -86,9 +83,6 @@ KS_DECLARE(ks_status_t) blade_upstreammgr_create(blade_upstreammgr_t **bumgrP, b
        ks_rwl_create(&bumgr->masterid_rwl, pool);
        ks_assert(bumgr->masterid_rwl);
 
-       ks_hash_create(&bumgr->realms, KS_HASH_MODE_CASE_INSENSITIVE, KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK | KS_HASH_FLAG_FREE_KEY, pool);
-       ks_assert(bumgr->realms);
-
        ks_pool_set_cleanup(bumgr, NULL, blade_upstreammgr_cleanup);
 
        *bumgrP = bumgr;
@@ -261,67 +255,6 @@ KS_DECLARE(ks_bool_t) blade_upstreammgr_masterlocal(blade_upstreammgr_t *bumgr)
        return ret;
 }
 
-KS_DECLARE(ks_status_t) blade_upstreammgr_realm_add(blade_upstreammgr_t *bumgr, const char *realm)
-{
-       char *key = NULL;
-
-       ks_assert(bumgr);
-       ks_assert(realm);
-
-       key = ks_pstrdup(ks_pool_get(bumgr), realm);
-       ks_hash_insert(bumgr->realms, (void *)key, (void *)KS_TRUE);
-
-       ks_log(KS_LOG_DEBUG, "Realm Added: %s\n", key);
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_upstreammgr_realm_remove(blade_upstreammgr_t *bumgr, const char *realm)
-{
-       ks_assert(bumgr);
-       ks_assert(realm);
-
-       ks_hash_remove(bumgr->realms, (void *)realm);
-
-       ks_log(KS_LOG_DEBUG, "Realm Removed: %s\n", realm);
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_upstreammgr_realm_clear(blade_upstreammgr_t *bumgr)
-{
-       ks_hash_iterator_t *it = NULL;
-
-       ks_assert(bumgr);
-
-       while ((it = ks_hash_first(bumgr->realms, KS_UNLOCKED))) {
-               void *key = NULL;
-               void *value = NULL;
-               ks_hash_this(it, (const void **)&key, NULL, &value);
-               ks_log(KS_LOG_DEBUG, "Realm Removed: %s\n", key);
-               ks_hash_remove(bumgr->realms, key);
-       }
-
-       return KS_STATUS_SUCCESS;
-}
-
-KS_DECLARE(ks_status_t) blade_upstreammgr_realm_propagate(blade_upstreammgr_t *bumgr, blade_session_t *bs)
-{
-       ks_assert(bumgr);
-       ks_assert(bs);
-
-       ks_hash_read_lock(bumgr->realms);
-       for (ks_hash_iterator_t *it = ks_hash_first(bumgr->realms, KS_UNLOCKED); it; it = ks_hash_next(&it)) {
-               void *key = NULL;
-               void *value = NULL;
-               ks_hash_this(it, (const void **)&key, NULL, &value);
-               blade_session_realm_add(bs, (const char *)key);
-       }
-       ks_hash_read_unlock(bumgr->realms);
-
-       return KS_STATUS_SUCCESS;
-}
-
 /* For Emacs:
  * Local Variables:
  * mode:c
index 6c40661a78cc96807f32a5d80be2fa9c9c5e3050..eb5d7d222b880a5dc5899e60e7f2fa94ab95b374 100644 (file)
@@ -44,7 +44,9 @@
 #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"
 #include "blade_tuple.h"
 
similarity index 66%
rename from libs/libblade/src/include/blade_module_master.h
rename to libs/libblade/src/include/blade_channel.h
index ea896f270b4682edf52fc959f818a9be00426c80..64885f6dd5258f48198db2318c555030f6d277d9 100644 (file)
@@ -1,23 +1,23 @@
 /*
  * 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
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _BLADE_MODULE_MASTER_H_
-#define _BLADE_MODULE_MASTER_H_
+#ifndef _BLADE_CHANNEL_H_
+#define _BLADE_CHANNEL_H_
 #include <blade.h>
 
 KS_BEGIN_EXTERN_C
-
-KS_DECLARE(ks_status_t) blade_module_master_create(blade_module_t **bmP, blade_handle_t *bh);
-
-KS_DECLARE(ks_status_t) blade_module_master_on_startup(blade_module_t *bm, config_setting_t *config);
-KS_DECLARE(ks_status_t) blade_module_master_on_shutdown(blade_module_t *bm);
-
+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_destroy(blade_channel_t **bcP);
+KS_DECLARE(const char *) blade_channel_name_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);
+KS_DECLARE(ks_status_t) blade_channel_write_unlock(blade_channel_t *bc);
+KS_DECLARE(ks_bool_t) blade_channel_authorization_verify(blade_channel_t *bc, const char *target);
+KS_DECLARE(ks_status_t) blade_channel_authorization_add(blade_channel_t *bc, const char *target);
+KS_DECLARE(ks_bool_t) blade_channel_authorization_remove(blade_channel_t *bc, const char *target);
 KS_END_EXTERN_C
 
 #endif
index 50fd67cae2a3967d7a4d93a7e5c0aa8e8989737e..12a97d220efffe5d49b7d51afccd0d848723edfd 100644 (file)
 KS_BEGIN_EXTERN_C
 KS_DECLARE(ks_status_t) blade_mastermgr_create(blade_mastermgr_t **bmmgrP, blade_handle_t *bh);
 KS_DECLARE(ks_status_t) blade_mastermgr_destroy(blade_mastermgr_t **bmmgrP);
+KS_DECLARE(ks_status_t) blade_mastermgr_startup(blade_mastermgr_t *bmmgr, config_setting_t *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(blade_protocol_t *) blade_mastermgr_protocol_lookup(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm);
-KS_DECLARE(ks_status_t) blade_mastermgr_controller_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, const char *controller);
-KS_DECLARE(ks_status_t) blade_mastermgr_controller_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, const char *controller);
-KS_DECLARE(ks_status_t) blade_mastermgr_channel_add(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, const char *channel);
-KS_DECLARE(ks_status_t) blade_mastermgr_channel_remove(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, const char *channel);
-KS_DECLARE(ks_status_t) blade_mastermgr_channel_authorize(blade_mastermgr_t *bmmgr, ks_bool_t remove, const char *protocol, const char *realm, const char *channel, const char *controller, const char *target);
-KS_DECLARE(ks_bool_t) blade_mastermgr_channel_verify(blade_mastermgr_t *bmmgr, const char *protocol, const char *realm, const char *channel, const char *target);
+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_END_EXTERN_C
 
 #endif
index 9a31b335b58f0f989fcdb9d8ab7f67e0911b4b62..cdbf74ce538f5c33504c6d6c1f3bc5c0b07f26f9 100644 (file)
 #include <blade.h>
 
 KS_BEGIN_EXTERN_C
-KS_DECLARE(ks_status_t) blade_protocol_create(blade_protocol_t **bpP, ks_pool_t *pool, const char *name, const char *realm);
+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_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(const char *) blade_protocol_realm_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);
+KS_DECLARE(ks_status_t) blade_protocol_write_lock(blade_protocol_t *bp);
+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_DECLARE(cJSON *) blade_protocol_controller_pack(blade_protocol_t *bp);
 KS_DECLARE(ks_status_t) blade_protocol_controller_add(blade_protocol_t *bp, const char *nodeid);
 KS_DECLARE(ks_bool_t) blade_protocol_controller_remove(blade_protocol_t *bp, const char *nodeid);
 KS_DECLARE(ks_bool_t) blade_protocol_controller_available(blade_protocol_t *bp);
-KS_DECLARE(ks_status_t) blade_protocol_channel_add(blade_protocol_t *bp, const char *name);
-KS_DECLARE(ks_bool_t) blade_protocol_channel_remove(blade_protocol_t *bp, const char *name);
-KS_DECLARE(ks_status_t) blade_protocol_channel_authorize(blade_protocol_t *bp, ks_bool_t remove, const char *channel, const char *controller, const char *target);
-KS_DECLARE(ks_bool_t) blade_protocol_channel_verify(blade_protocol_t *bp, const char *channel, const char *target);
+KS_DECLARE(blade_channel_t *) blade_protocol_channel_lookup(blade_protocol_t *bp, const char *channel, ks_bool_t writelocked);
+KS_DECLARE(ks_bool_t) blade_protocol_controller_verify(blade_protocol_t *bp, const char *controller);
+KS_DECLARE(ks_status_t) blade_protocol_channel_add(blade_protocol_t *bp, blade_channel_t *channel);
+KS_DECLARE(ks_bool_t) blade_protocol_channel_remove(blade_protocol_t *bp, const char *channel);
 KS_END_EXTERN_C
 
 #endif
diff --git a/libs/libblade/src/include/blade_realm.h b/libs/libblade/src/include/blade_realm.h
new file mode 100644 (file)
index 0000000..1e70f5c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * 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 f64326ffde3285624d5e36eff88d84e0b2c539ac..4e9c03438e6b8a4e0109d7075dd00118f848f972 100644 (file)
@@ -77,6 +77,10 @@ KS_DECLARE(ks_status_t) blade_handle_rpcsubscribe(blade_handle_t *bh, blade_rpcs
 
 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(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);
 
 KS_END_EXTERN_C
 
index d6bf895ff50850f8adcb2205997d40ba6a605c50..db1c0b3ed2a7f9e5457dc7c56689b76a63806336 100644 (file)
@@ -48,7 +48,9 @@ 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;
 typedef struct blade_tuple_s blade_tuple_t;
 
index a44dfe735a1c14898844635041e9daca9bfcf0ba..d662560affbac0b21927513858f51f33f1b35332 100644 (file)
@@ -48,11 +48,6 @@ KS_DECLARE(ks_status_t) blade_upstreammgr_masterid_set(blade_upstreammgr_t *bumg
 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_DECLARE(ks_hash_t *) blade_upstreammgr_realm_lookup(blade_handle_t *bh);
-KS_DECLARE(ks_status_t) blade_upstreammgr_realm_add(blade_upstreammgr_t *bumgr, const char *realm);
-KS_DECLARE(ks_status_t) blade_upstreammgr_realm_remove(blade_upstreammgr_t *bumgr, const char *realm);
-KS_DECLARE(ks_status_t) blade_upstreammgr_realm_clear(blade_upstreammgr_t *bumgr);
-KS_DECLARE(ks_status_t) blade_upstreammgr_realm_propagate(blade_upstreammgr_t *bumgr, blade_session_t *bs);
 
 KS_END_EXTERN_C
 
index 810ecb348112cde86426dcf2e45c16cf0dfc4755..3394576da9eacc9bd999cafba05e0657c82b56ea 100644 (file)
@@ -18,11 +18,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);
 
 static const struct command_def_s command_defs[] = {
        { "quit", command_quit },
        { "channeladd", command_channeladd },
        { "channelremove", command_channelremove },
+       { "presence", command_presence },
 
        { NULL, NULL }
 };
@@ -323,6 +325,39 @@ ks_bool_t test_talk_request_handler(blade_rpc_request_t *brpcreq, void *data)
        return KS_FALSE;
 }
 
+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;
+       cJSON *params = NULL;
+       const char *nodeid = NULL;
+
+       ks_assert(brpcreq);
+       ks_assert(data);
+
+       bh = blade_rpc_request_handle_get(brpcreq);
+       ks_assert(bh);
+
+       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);
+
+       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);
+
+       return KS_FALSE;
+}
+
 
 int main(int argc, char **argv)
 {
@@ -525,6 +560,20 @@ void command_channelremove(blade_handle_t *bh, char *args)
        }
 }
 
+void command_presence(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);
+}
+
 /* For Emacs:
 * Local Variables:
 * mode:c