2017-07-03 12:48:46 -06:00
/*
* 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_mastermgr_s {
blade_handle_t * handle ;
ks_pool_t * pool ;
// @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?
2017-07-25 11:00:45 -06:00
ks_hash_t * protocols ; // protocols that have been published with blade.publish, and the details to locate a protocol controller with blade.locate
2017-07-03 12:48:46 -06:00
} ;
static void blade_mastermgr_cleanup ( ks_pool_t * pool , void * ptr , void * arg , ks_pool_cleanup_action_t action , ks_pool_cleanup_type_t type )
{
//blade_mastermgr_t *bmmgr = (blade_mastermgr_t *)ptr;
//ks_assert(bmmgr);
switch ( action ) {
case KS_MPCL_ANNOUNCE :
break ;
case KS_MPCL_TEARDOWN :
break ;
case KS_MPCL_DESTROY :
break ;
}
}
KS_DECLARE ( ks_status_t ) blade_mastermgr_create ( blade_mastermgr_t * * bmmgrP , blade_handle_t * bh )
{
ks_pool_t * pool = NULL ;
blade_mastermgr_t * bmmgr = NULL ;
ks_assert ( bmmgrP ) ;
ks_pool_open ( & pool ) ;
ks_assert ( pool ) ;
bmmgr = ks_pool_alloc ( pool , sizeof ( blade_mastermgr_t ) ) ;
bmmgr - > handle = bh ;
bmmgr - > pool = pool ;
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 , bmmgr - > pool ) ;
ks_assert ( bmmgr - > protocols ) ;
ks_pool_set_cleanup ( pool , bmmgr , NULL , blade_mastermgr_cleanup ) ;
* bmmgrP = bmmgr ;
return KS_STATUS_SUCCESS ;
}
KS_DECLARE ( ks_status_t ) blade_mastermgr_destroy ( blade_mastermgr_t * * bmmgrP )
{
blade_mastermgr_t * bmmgr = NULL ;
ks_pool_t * pool ;
ks_assert ( bmmgrP ) ;
ks_assert ( * bmmgrP ) ;
bmmgr = * bmmgrP ;
* bmmgrP = NULL ;
ks_assert ( bmmgr ) ;
pool = bmmgr - > pool ;
ks_pool_close ( & pool ) ;
return KS_STATUS_SUCCESS ;
}
KS_DECLARE ( blade_handle_t * ) blade_mastermgr_handle_get ( blade_mastermgr_t * bmmgr )
{
ks_assert ( bmmgr ) ;
return bmmgr - > handle ;
}
2017-07-25 11:00:45 -06:00
KS_DECLARE ( ks_status_t ) blade_mastermgr_purge ( blade_mastermgr_t * bmmgr , const char * nodeid )
{
ks_hash_t * cleanup = NULL ;
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_this ( it , ( const void * * ) & key , NULL , ( void * * ) & bp ) ;
if ( blade_protocol_purge ( bp , nodeid ) ) {
if ( ! cleanup ) ks_hash_create ( & cleanup , KS_HASH_MODE_CASE_INSENSITIVE , KS_HASH_FLAG_RWLOCK | KS_HASH_FLAG_DUP_CHECK , bmmgr - > pool ) ;
ks_hash_insert ( cleanup , key , bp ) ;
}
}
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 ) ;
ks_log ( KS_LOG_DEBUG , " Protocol Removed: %s \n " , key ) ;
ks_hash_remove ( bmmgr - > protocols , key ) ;
}
ks_hash_destroy ( & cleanup ) ;
}
ks_hash_write_unlock ( bmmgr - > protocols ) ;
return KS_STATUS_SUCCESS ;
}
2017-07-03 12:48:46 -06:00
KS_DECLARE ( blade_protocol_t * ) blade_mastermgr_protocol_lookup ( blade_mastermgr_t * bmmgr , const char * protocol , const char * realm )
{
blade_protocol_t * bp = NULL ;
char * key = NULL ;
ks_assert ( bmmgr ) ;
ks_assert ( protocol ) ;
ks_assert ( realm ) ;
key = ks_psprintf ( bmmgr - > pool , " %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 ) ;
return bp ;
}
KS_DECLARE ( ks_status_t ) blade_mastermgr_controller_add ( blade_mastermgr_t * bmmgr , const char * protocol , const char * realm , const char * controller )
{
blade_protocol_t * bp = NULL ;
char * key = NULL ;
ks_assert ( bmmgr ) ;
ks_assert ( protocol ) ;
ks_assert ( realm ) ;
ks_assert ( controller ) ;
key = ks_psprintf ( bmmgr - > pool , " %s@%s " , protocol , realm ) ;
ks_hash_write_lock ( bmmgr - > protocols ) ;
bp = ( blade_protocol_t * ) ks_hash_search ( bmmgr - > protocols , ( void * ) key , KS_UNLOCKED ) ;
if ( bp ) {
// @todo deal with exclusive stuff when the protocol is already registered
}
if ( ! bp ) {
blade_protocol_create ( & bp , bmmgr - > pool , protocol , realm ) ;
ks_assert ( bp ) ;
ks_log ( KS_LOG_DEBUG , " Protocol Added: %s \n " , key ) ;
ks_hash_insert ( bmmgr - > protocols , ( void * ) ks_pstrdup ( bmmgr - > pool , key ) , bp ) ;
}
blade_protocol_controllers_add ( bp , controller ) ;
2017-07-25 11:00:45 -06:00
ks_pool_free ( bmmgr - > pool , & key ) ;
2017-07-03 12:48:46 -06:00
ks_hash_write_unlock ( bmmgr - > protocols ) ;
return KS_STATUS_SUCCESS ;
}
2017-07-25 11:00:45 -06:00
KS_DECLARE ( ks_status_t ) blade_mastermgr_channel_add ( blade_mastermgr_t * bmmgr , const char * protocol , const char * realm , const char * channel )
2017-07-03 12:48:46 -06:00
{
2017-07-25 11:00:45 -06:00
ks_status_t ret = KS_STATUS_SUCCESS ;
blade_protocol_t * bp = NULL ;
char * key = NULL ;
2017-07-03 12:48:46 -06:00
ks_assert ( bmmgr ) ;
2017-07-25 11:00:45 -06:00
ks_assert ( protocol ) ;
ks_assert ( realm ) ;
ks_assert ( channel ) ;
2017-07-03 12:48:46 -06:00
2017-07-25 11:00:45 -06:00
key = ks_psprintf ( bmmgr - > pool , " %s@%s " , protocol , realm ) ;
2017-07-03 12:48:46 -06:00
2017-07-25 11:00:45 -06:00
bp = ( blade_protocol_t * ) ks_hash_search ( bmmgr - > protocols , ( void * ) key , KS_READLOCKED ) ;
if ( ! bp ) {
ret = KS_STATUS_NOT_FOUND ;
goto done ;
}
2017-07-03 12:48:46 -06:00
2017-07-25 11:00:45 -06:00
blade_protocol_channel_add ( bp , channel ) ;
2017-07-03 12:48:46 -06:00
2017-07-25 11:00:45 -06:00
done :
ks_pool_free ( bmmgr - > pool , & key ) ;
2017-07-03 12:48:46 -06:00
2017-07-25 11:00:45 -06:00
ks_hash_read_unlock ( bmmgr - > protocols ) ;
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_status_t ret = KS_STATUS_SUCCESS ;
blade_protocol_t * bp = NULL ;
char * key = NULL ;
ks_assert ( bmmgr ) ;
ks_assert ( protocol ) ;
ks_assert ( realm ) ;
ks_assert ( channel ) ;
key = ks_psprintf ( bmmgr - > pool , " %s@%s " , protocol , realm ) ;
bp = ( blade_protocol_t * ) ks_hash_search ( bmmgr - > protocols , ( void * ) key , KS_READLOCKED ) ;
if ( ! bp ) {
ret = KS_STATUS_NOT_FOUND ;
goto done ;
2017-07-03 12:48:46 -06:00
}
2017-07-25 11:00:45 -06:00
blade_protocol_channel_remove ( bp , channel ) ;
done :
ks_pool_free ( bmmgr - > pool , & key ) ;
ks_hash_read_unlock ( bmmgr - > protocols ) ;
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_status_t ret = KS_STATUS_SUCCESS ;
blade_protocol_t * bp = NULL ;
char * key = NULL ;
//ks_hash_t *cleanup = NULL;
ks_assert ( bmmgr ) ;
ks_assert ( protocol ) ;
ks_assert ( realm ) ;
ks_assert ( channel ) ;
ks_assert ( controller ) ;
ks_assert ( target ) ;
key = ks_psprintf ( bmmgr - > pool , " %s@%s " , protocol , realm ) ;
bp = ( blade_protocol_t * ) ks_hash_search ( bmmgr - > protocols , ( void * ) key , KS_READLOCKED ) ;
if ( ! bp ) {
ret = KS_STATUS_NOT_FOUND ;
goto done ;
}
ret = blade_protocol_channel_authorize ( bp , remove , channel , controller , target ) ;
done :
ks_pool_free ( bmmgr - > pool , & key ) ;
ks_hash_read_unlock ( bmmgr - > protocols ) ;
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_bool_t ret = KS_FALSE ;
blade_protocol_t * bp = NULL ;
char * key = NULL ;
//ks_hash_t *cleanup = NULL;
ks_assert ( bmmgr ) ;
ks_assert ( protocol ) ;
ks_assert ( realm ) ;
ks_assert ( channel ) ;
ks_assert ( target ) ;
key = ks_psprintf ( bmmgr - > pool , " %s@%s " , protocol , realm ) ;
bp = ( blade_protocol_t * ) ks_hash_search ( bmmgr - > protocols , ( void * ) key , KS_READLOCKED ) ;
if ( ! bp ) goto done ;
ret = blade_protocol_channel_verify ( bp , channel , target ) ;
done :
ks_pool_free ( bmmgr - > pool , & key ) ;
ks_hash_read_unlock ( bmmgr - > protocols ) ;
return ret ;
2017-07-03 12:48:46 -06:00
}
/* 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 :
*/