FS-10167: Preliminary support for blade.execute, tested with a basic test.echo across 3 nodes with a common master. Multitier routing is not yet fully supported
This commit is contained in:
parent
14d4f8d565
commit
076a9adbf6
|
@ -190,7 +190,7 @@
|
|||
<ClCompile Include="src\blade.c" />
|
||||
<ClCompile Include="src\blade_connection.c" />
|
||||
<ClCompile Include="src\blade_identity.c" />
|
||||
<ClCompile Include="src\blade_jsonrpc.c" />
|
||||
<ClCompile Include="src\blade_rpc.c" />
|
||||
<ClCompile Include="src\blade_protocol.c" />
|
||||
<ClCompile Include="src\blade_transport_wss.c" />
|
||||
<ClCompile Include="src\blade_session.c" />
|
||||
|
@ -202,7 +202,7 @@
|
|||
<ClInclude Include="src\include\blade.h" />
|
||||
<ClInclude Include="src\include\blade_connection.h" />
|
||||
<ClInclude Include="src\include\blade_identity.h" />
|
||||
<ClInclude Include="src\include\blade_jsonrpc.h" />
|
||||
<ClInclude Include="src\include\blade_rpc.h" />
|
||||
<ClInclude Include="src\include\blade_protocol.h" />
|
||||
<ClInclude Include="src\include\blade_transport_wss.h" />
|
||||
<ClInclude Include="src\include\blade_session.h" />
|
||||
|
|
|
@ -36,15 +36,15 @@
|
|||
<ClCompile Include="src\blade_transport.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\blade_jsonrpc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\blade_transport_wss.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\blade_protocol.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\blade_rpc.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\include\unqlite.h">
|
||||
|
@ -71,14 +71,14 @@
|
|||
<ClInclude Include="src\include\blade_transport.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\include\blade_jsonrpc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\include\blade_transport_wss.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\include\blade_protocol.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\include\blade_rpc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -1,432 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Shane Bryldt
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "blade.h"
|
||||
|
||||
struct blade_jsonrpc_s {
|
||||
blade_handle_t *handle;
|
||||
ks_pool_t *pool;
|
||||
|
||||
const char *method;
|
||||
|
||||
blade_jsonrpc_request_callback_t callback;
|
||||
void *callback_data;
|
||||
};
|
||||
|
||||
struct blade_jsonrpc_request_s {
|
||||
blade_handle_t *handle;
|
||||
ks_pool_t *pool;
|
||||
|
||||
const char *session_id;
|
||||
|
||||
cJSON *message;
|
||||
const char *message_id; // pulled from message for easier keying
|
||||
blade_jsonrpc_response_callback_t callback;
|
||||
// @todo ttl to wait for response before injecting an error response locally
|
||||
};
|
||||
|
||||
struct blade_jsonrpc_response_s {
|
||||
blade_handle_t *handle;
|
||||
ks_pool_t *pool;
|
||||
|
||||
const char *session_id;
|
||||
|
||||
blade_jsonrpc_request_t *request;
|
||||
|
||||
cJSON *message;
|
||||
};
|
||||
|
||||
|
||||
static void blade_jsonrpc_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
|
||||
{
|
||||
//blade_jsonrpc_t *bjsonrpc = (blade_jsonrpc_t *)ptr;
|
||||
|
||||
//ks_assert(bjsonrpc);
|
||||
|
||||
switch (action) {
|
||||
case KS_MPCL_ANNOUNCE:
|
||||
break;
|
||||
case KS_MPCL_TEARDOWN:
|
||||
break;
|
||||
case KS_MPCL_DESTROY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_create(blade_jsonrpc_t **bjsonrpcP, blade_handle_t *bh, const char *method, blade_jsonrpc_request_callback_t callback, void *callback_data)
|
||||
{
|
||||
blade_jsonrpc_t *bjsonrpc = NULL;
|
||||
ks_pool_t *pool = NULL;
|
||||
|
||||
ks_assert(bjsonrpcP);
|
||||
ks_assert(bh);
|
||||
ks_assert(method);
|
||||
ks_assert(callback);
|
||||
|
||||
ks_pool_open(&pool);
|
||||
ks_assert(pool);
|
||||
|
||||
bjsonrpc = ks_pool_alloc(pool, sizeof(blade_jsonrpc_t));
|
||||
bjsonrpc->handle = bh;
|
||||
bjsonrpc->pool = pool;
|
||||
bjsonrpc->method = ks_pstrdup(pool, method);
|
||||
bjsonrpc->callback = callback;
|
||||
bjsonrpc->callback_data = callback_data;
|
||||
|
||||
ks_pool_set_cleanup(pool, bjsonrpc, NULL, blade_jsonrpc_cleanup);
|
||||
|
||||
*bjsonrpcP = bjsonrpc;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_destroy(blade_jsonrpc_t **bjsonrpcP)
|
||||
{
|
||||
blade_jsonrpc_t *bjsonrpc = NULL;
|
||||
ks_pool_t *pool = NULL;
|
||||
|
||||
ks_assert(bjsonrpcP);
|
||||
ks_assert(*bjsonrpcP);
|
||||
|
||||
bjsonrpc = *bjsonrpcP;
|
||||
|
||||
pool = bjsonrpc->pool;
|
||||
|
||||
ks_pool_close(&pool);
|
||||
|
||||
*bjsonrpcP = NULL;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_handle_t *) blade_jsonrpc_handle_get(blade_jsonrpc_t *bjsonrpc)
|
||||
{
|
||||
ks_assert(bjsonrpc);
|
||||
|
||||
return bjsonrpc->handle;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_jsonrpc_method_get(blade_jsonrpc_t *bjsonrpc)
|
||||
{
|
||||
ks_assert(bjsonrpc);
|
||||
|
||||
return bjsonrpc->method;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_jsonrpc_request_callback_t) blade_jsonrpc_callback_get(blade_jsonrpc_t *bjsonrpc)
|
||||
{
|
||||
ks_assert(bjsonrpc);
|
||||
|
||||
return bjsonrpc->callback;
|
||||
}
|
||||
|
||||
KS_DECLARE(void *) blade_jsonrpc_callback_data_get(blade_jsonrpc_t *bjsonrpc)
|
||||
{
|
||||
ks_assert(bjsonrpc);
|
||||
|
||||
return bjsonrpc->callback_data;
|
||||
}
|
||||
|
||||
|
||||
static void blade_jsonrpc_request_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
|
||||
{
|
||||
blade_jsonrpc_request_t *bjsonrpcreq = (blade_jsonrpc_request_t *)ptr;
|
||||
|
||||
ks_assert(bjsonrpcreq);
|
||||
|
||||
switch (action) {
|
||||
case KS_MPCL_ANNOUNCE:
|
||||
break;
|
||||
case KS_MPCL_TEARDOWN:
|
||||
ks_pool_free(bjsonrpcreq->pool, (void **)&bjsonrpcreq->session_id);
|
||||
cJSON_Delete(bjsonrpcreq->message);
|
||||
break;
|
||||
case KS_MPCL_DESTROY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_request_create(blade_jsonrpc_request_t **bjsonrpcreqP,
|
||||
blade_handle_t *bh,
|
||||
ks_pool_t *pool,
|
||||
const char *session_id,
|
||||
cJSON *json,
|
||||
blade_jsonrpc_response_callback_t callback)
|
||||
{
|
||||
blade_jsonrpc_request_t *bjsonrpcreq = NULL;
|
||||
|
||||
ks_assert(bjsonrpcreqP);
|
||||
ks_assert(bh);
|
||||
ks_assert(pool);
|
||||
ks_assert(session_id);
|
||||
ks_assert(json);
|
||||
|
||||
bjsonrpcreq = ks_pool_alloc(pool, sizeof(blade_jsonrpc_request_t));
|
||||
bjsonrpcreq->handle = bh;
|
||||
bjsonrpcreq->pool = pool;
|
||||
bjsonrpcreq->session_id = ks_pstrdup(pool, session_id);
|
||||
bjsonrpcreq->message = cJSON_Duplicate(json, 1);
|
||||
bjsonrpcreq->message_id = cJSON_GetObjectCstr(bjsonrpcreq->message, "id");
|
||||
bjsonrpcreq->callback = callback;
|
||||
|
||||
ks_pool_set_cleanup(pool, bjsonrpcreq, NULL, blade_jsonrpc_request_cleanup);
|
||||
|
||||
*bjsonrpcreqP = bjsonrpcreq;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_request_destroy(blade_jsonrpc_request_t **bjsonrpcreqP)
|
||||
{
|
||||
blade_jsonrpc_request_t *bjsonrpcreq = NULL;
|
||||
|
||||
ks_assert(bjsonrpcreqP);
|
||||
ks_assert(*bjsonrpcreqP);
|
||||
|
||||
bjsonrpcreq = *bjsonrpcreqP;
|
||||
|
||||
ks_pool_free(bjsonrpcreq->pool, bjsonrpcreqP);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_handle_t *) blade_jsonrpc_request_handle_get(blade_jsonrpc_request_t *bjsonrpcreq)
|
||||
{
|
||||
ks_assert(bjsonrpcreq);
|
||||
return bjsonrpcreq->handle;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_jsonrpc_request_sessionid_get(blade_jsonrpc_request_t *bjsonrpcreq)
|
||||
{
|
||||
ks_assert(bjsonrpcreq);
|
||||
return bjsonrpcreq->session_id;
|
||||
}
|
||||
|
||||
KS_DECLARE(cJSON *) blade_jsonrpc_request_message_get(blade_jsonrpc_request_t *bjsonrpcreq)
|
||||
{
|
||||
ks_assert(bjsonrpcreq);
|
||||
return bjsonrpcreq->message;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_jsonrpc_request_messageid_get(blade_jsonrpc_request_t *bjsonrpcreq)
|
||||
{
|
||||
ks_assert(bjsonrpcreq);
|
||||
return bjsonrpcreq->message_id;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_jsonrpc_response_callback_t) blade_jsonrpc_request_callback_get(blade_jsonrpc_request_t *bjsonrpcreq)
|
||||
{
|
||||
ks_assert(bjsonrpcreq);
|
||||
return bjsonrpcreq->callback;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_request_raw_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
cJSON *p = NULL;
|
||||
uuid_t msgid;
|
||||
const char *mid = NULL;
|
||||
|
||||
ks_assert(pool);
|
||||
ks_assert(json);
|
||||
ks_assert(method);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||
|
||||
ks_uuid(&msgid);
|
||||
mid = ks_uuid_str(pool, &msgid);
|
||||
cJSON_AddStringToObject(root, "id", mid);
|
||||
ks_pool_free(pool, &mid);
|
||||
|
||||
cJSON_AddStringToObject(root, "method", method);
|
||||
|
||||
p = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "params", p);
|
||||
|
||||
*json = root;
|
||||
if (params) *params = p;
|
||||
if (id) *id = cJSON_GetObjectCstr(root, "id");
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void blade_jsonrpc_response_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
|
||||
{
|
||||
blade_jsonrpc_response_t *bjsonrpcres = (blade_jsonrpc_response_t *)ptr;
|
||||
|
||||
ks_assert(bjsonrpcres);
|
||||
|
||||
switch (action) {
|
||||
case KS_MPCL_ANNOUNCE:
|
||||
break;
|
||||
case KS_MPCL_TEARDOWN:
|
||||
ks_pool_free(bjsonrpcres->pool, (void **)&bjsonrpcres->session_id);
|
||||
blade_jsonrpc_request_destroy(&bjsonrpcres->request);
|
||||
cJSON_Delete(bjsonrpcres->message);
|
||||
break;
|
||||
case KS_MPCL_DESTROY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_response_create(blade_jsonrpc_response_t **bjsonrpcresP,
|
||||
blade_handle_t *bh,
|
||||
ks_pool_t *pool,
|
||||
const char *session_id,
|
||||
blade_jsonrpc_request_t *bjsonrpcreq,
|
||||
cJSON *json)
|
||||
{
|
||||
blade_jsonrpc_response_t *bjsonrpcres = NULL;
|
||||
|
||||
ks_assert(bjsonrpcresP);
|
||||
ks_assert(bh);
|
||||
ks_assert(pool);
|
||||
ks_assert(session_id);
|
||||
ks_assert(bjsonrpcreq);
|
||||
ks_assert(json);
|
||||
|
||||
bjsonrpcres = ks_pool_alloc(pool, sizeof(blade_jsonrpc_response_t));
|
||||
bjsonrpcres->handle = bh;
|
||||
bjsonrpcres->pool = pool;
|
||||
bjsonrpcres->session_id = ks_pstrdup(pool, session_id);
|
||||
bjsonrpcres->request = bjsonrpcreq;
|
||||
bjsonrpcres->message = cJSON_Duplicate(json, 1);
|
||||
|
||||
ks_pool_set_cleanup(pool, bjsonrpcres, NULL, blade_jsonrpc_response_cleanup);
|
||||
|
||||
*bjsonrpcresP = bjsonrpcres;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_response_destroy(blade_jsonrpc_response_t **bjsonrpcresP)
|
||||
{
|
||||
blade_jsonrpc_response_t *bjsonrpcres = NULL;
|
||||
|
||||
ks_assert(bjsonrpcresP);
|
||||
ks_assert(*bjsonrpcresP);
|
||||
|
||||
bjsonrpcres = *bjsonrpcresP;
|
||||
|
||||
ks_pool_free(bjsonrpcres->pool, bjsonrpcresP);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_response_raw_create(cJSON **json, cJSON **result, const char *id)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
cJSON *r = NULL;
|
||||
|
||||
ks_assert(json);
|
||||
ks_assert(id);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||
|
||||
cJSON_AddStringToObject(root, "id", id);
|
||||
|
||||
r = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "result", r);
|
||||
|
||||
*json = root;
|
||||
if (result) *result = r;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_handle_t *) blade_jsonrpc_response_handle_get(blade_jsonrpc_response_t *bjsonrpcres)
|
||||
{
|
||||
ks_assert(bjsonrpcres);
|
||||
return bjsonrpcres->handle;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_jsonrpc_response_sessionid_get(blade_jsonrpc_response_t *bjsonrpcres)
|
||||
{
|
||||
ks_assert(bjsonrpcres);
|
||||
return bjsonrpcres->session_id;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_jsonrpc_request_t *) blade_jsonrpc_response_request_get(blade_jsonrpc_response_t *bjsonrpcres)
|
||||
{
|
||||
ks_assert(bjsonrpcres);
|
||||
return bjsonrpcres->request;
|
||||
}
|
||||
|
||||
KS_DECLARE(cJSON *) blade_jsonrpc_response_message_get(blade_jsonrpc_response_t *bjsonrpcres)
|
||||
{
|
||||
ks_assert(bjsonrpcres);
|
||||
return bjsonrpcres->message;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_error_raw_create(cJSON **json, cJSON **error, const char *id, int32_t code, const char *message)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
cJSON *e = NULL;
|
||||
|
||||
ks_assert(json);
|
||||
//ks_assert(id);
|
||||
ks_assert(message);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||
|
||||
if (id) cJSON_AddStringToObject(root, "id", id);
|
||||
|
||||
e = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(e, "code", code);
|
||||
cJSON_AddStringToObject(e, "message", message);
|
||||
cJSON_AddItemToObject(root, "error", e);
|
||||
|
||||
*json = root;
|
||||
if (error) *error = e;
|
||||
|
||||
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:
|
||||
*/
|
|
@ -0,0 +1,465 @@
|
|||
/*
|
||||
* 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_rpc_s {
|
||||
blade_handle_t *handle;
|
||||
ks_pool_t *pool;
|
||||
|
||||
const char *method;
|
||||
const char *protocol;
|
||||
const char *realm;
|
||||
|
||||
blade_rpc_request_callback_t callback;
|
||||
void *callback_data;
|
||||
};
|
||||
|
||||
struct blade_rpc_request_s {
|
||||
blade_handle_t *handle;
|
||||
ks_pool_t *pool;
|
||||
|
||||
const char *session_id;
|
||||
|
||||
cJSON *message;
|
||||
const char *message_id; // pulled from message for easier keying
|
||||
blade_rpc_response_callback_t callback;
|
||||
void *callback_data;
|
||||
// @todo ttl to wait for response before injecting an error response locally
|
||||
};
|
||||
|
||||
struct blade_rpc_response_s {
|
||||
blade_handle_t *handle;
|
||||
ks_pool_t *pool;
|
||||
|
||||
const char *session_id;
|
||||
|
||||
blade_rpc_request_t *request;
|
||||
|
||||
cJSON *message;
|
||||
};
|
||||
|
||||
|
||||
static void blade_rpc_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
|
||||
{
|
||||
//blade_rpc_t *brpc = (blade_rpc_t *)ptr;
|
||||
|
||||
//ks_assert(brpc);
|
||||
|
||||
switch (action) {
|
||||
case KS_MPCL_ANNOUNCE:
|
||||
break;
|
||||
case KS_MPCL_TEARDOWN:
|
||||
break;
|
||||
case KS_MPCL_DESTROY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_create(blade_rpc_t **brpcP, blade_handle_t *bh, const char *method, const char *protocol, const char *realm, blade_rpc_request_callback_t callback, void *callback_data)
|
||||
{
|
||||
blade_rpc_t *brpc = NULL;
|
||||
ks_pool_t *pool = NULL;
|
||||
|
||||
ks_assert(brpcP);
|
||||
ks_assert(bh);
|
||||
ks_assert(method);
|
||||
ks_assert(callback);
|
||||
|
||||
ks_pool_open(&pool);
|
||||
ks_assert(pool);
|
||||
|
||||
brpc = ks_pool_alloc(pool, sizeof(blade_rpc_t));
|
||||
brpc->handle = bh;
|
||||
brpc->pool = pool;
|
||||
brpc->method = ks_pstrdup(pool, method);
|
||||
if (protocol) brpc->protocol = ks_pstrdup(pool, protocol);
|
||||
if (realm) brpc->realm = ks_pstrdup(pool, realm);
|
||||
brpc->callback = callback;
|
||||
brpc->callback_data = callback_data;
|
||||
|
||||
ks_pool_set_cleanup(pool, brpc, NULL, blade_rpc_cleanup);
|
||||
|
||||
*brpcP = brpc;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_destroy(blade_rpc_t **brpcP)
|
||||
{
|
||||
blade_rpc_t *brpc = NULL;
|
||||
ks_pool_t *pool = NULL;
|
||||
|
||||
ks_assert(brpcP);
|
||||
ks_assert(*brpcP);
|
||||
|
||||
brpc = *brpcP;
|
||||
|
||||
pool = brpc->pool;
|
||||
|
||||
ks_pool_close(&pool);
|
||||
|
||||
*brpcP = NULL;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_handle_t *) blade_rpc_handle_get(blade_rpc_t *brpc)
|
||||
{
|
||||
ks_assert(brpc);
|
||||
|
||||
return brpc->handle;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_rpc_method_get(blade_rpc_t *brpc)
|
||||
{
|
||||
ks_assert(brpc);
|
||||
|
||||
return brpc->method;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_rpc_protocol_get(blade_rpc_t *brpc)
|
||||
{
|
||||
ks_assert(brpc);
|
||||
|
||||
return brpc->protocol;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_rpc_realm_get(blade_rpc_t *brpc)
|
||||
{
|
||||
ks_assert(brpc);
|
||||
|
||||
return brpc->realm;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_rpc_request_callback_t) blade_rpc_callback_get(blade_rpc_t *brpc)
|
||||
{
|
||||
ks_assert(brpc);
|
||||
|
||||
return brpc->callback;
|
||||
}
|
||||
|
||||
KS_DECLARE(void *) blade_rpc_callback_data_get(blade_rpc_t *brpc)
|
||||
{
|
||||
ks_assert(brpc);
|
||||
|
||||
return brpc->callback_data;
|
||||
}
|
||||
|
||||
|
||||
static void blade_rpc_request_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
|
||||
{
|
||||
blade_rpc_request_t *brpcreq = (blade_rpc_request_t *)ptr;
|
||||
|
||||
ks_assert(brpcreq);
|
||||
|
||||
switch (action) {
|
||||
case KS_MPCL_ANNOUNCE:
|
||||
break;
|
||||
case KS_MPCL_TEARDOWN:
|
||||
ks_pool_free(brpcreq->pool, (void **)&brpcreq->session_id);
|
||||
cJSON_Delete(brpcreq->message);
|
||||
break;
|
||||
case KS_MPCL_DESTROY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_request_create(blade_rpc_request_t **brpcreqP,
|
||||
blade_handle_t *bh,
|
||||
ks_pool_t *pool,
|
||||
const char *session_id,
|
||||
cJSON *json,
|
||||
blade_rpc_response_callback_t callback,
|
||||
void *data)
|
||||
{
|
||||
blade_rpc_request_t *brpcreq = NULL;
|
||||
|
||||
ks_assert(brpcreqP);
|
||||
ks_assert(bh);
|
||||
ks_assert(pool);
|
||||
ks_assert(session_id);
|
||||
ks_assert(json);
|
||||
|
||||
brpcreq = ks_pool_alloc(pool, sizeof(blade_rpc_request_t));
|
||||
brpcreq->handle = bh;
|
||||
brpcreq->pool = pool;
|
||||
brpcreq->session_id = ks_pstrdup(pool, session_id);
|
||||
brpcreq->message = cJSON_Duplicate(json, 1);
|
||||
brpcreq->message_id = cJSON_GetObjectCstr(brpcreq->message, "id");
|
||||
brpcreq->callback = callback;
|
||||
brpcreq->callback_data = data;
|
||||
|
||||
ks_pool_set_cleanup(pool, brpcreq, NULL, blade_rpc_request_cleanup);
|
||||
|
||||
*brpcreqP = brpcreq;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_request_destroy(blade_rpc_request_t **brpcreqP)
|
||||
{
|
||||
blade_rpc_request_t *brpcreq = NULL;
|
||||
|
||||
ks_assert(brpcreqP);
|
||||
ks_assert(*brpcreqP);
|
||||
|
||||
brpcreq = *brpcreqP;
|
||||
|
||||
ks_pool_free(brpcreq->pool, brpcreqP);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_request_duplicate(blade_rpc_request_t **brpcreqP, blade_rpc_request_t *brpcreq)
|
||||
{
|
||||
return blade_rpc_request_create(brpcreqP, brpcreq->handle, brpcreq->pool, brpcreq->session_id, brpcreq->message, brpcreq->callback, brpcreq->callback_data);
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_handle_t *) blade_rpc_request_handle_get(blade_rpc_request_t *brpcreq)
|
||||
{
|
||||
ks_assert(brpcreq);
|
||||
return brpcreq->handle;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_rpc_request_sessionid_get(blade_rpc_request_t *brpcreq)
|
||||
{
|
||||
ks_assert(brpcreq);
|
||||
return brpcreq->session_id;
|
||||
}
|
||||
|
||||
KS_DECLARE(cJSON *) blade_rpc_request_message_get(blade_rpc_request_t *brpcreq)
|
||||
{
|
||||
ks_assert(brpcreq);
|
||||
return brpcreq->message;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_rpc_request_messageid_get(blade_rpc_request_t *brpcreq)
|
||||
{
|
||||
ks_assert(brpcreq);
|
||||
return brpcreq->message_id;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_rpc_response_callback_t) blade_rpc_request_callback_get(blade_rpc_request_t *brpcreq)
|
||||
{
|
||||
ks_assert(brpcreq);
|
||||
return brpcreq->callback;
|
||||
}
|
||||
|
||||
KS_DECLARE(void *) blade_rpc_request_callback_data_get(blade_rpc_request_t *brpcreq)
|
||||
{
|
||||
ks_assert(brpcreq);
|
||||
|
||||
return brpcreq->callback_data;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_request_raw_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
cJSON *p = NULL;
|
||||
uuid_t msgid;
|
||||
const char *mid = NULL;
|
||||
|
||||
ks_assert(pool);
|
||||
ks_assert(json);
|
||||
ks_assert(method);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||
|
||||
ks_uuid(&msgid);
|
||||
mid = ks_uuid_str(pool, &msgid);
|
||||
cJSON_AddStringToObject(root, "id", mid);
|
||||
ks_pool_free(pool, &mid);
|
||||
|
||||
cJSON_AddStringToObject(root, "method", method);
|
||||
|
||||
p = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "params", p);
|
||||
|
||||
*json = root;
|
||||
if (params) *params = p;
|
||||
if (id) *id = cJSON_GetObjectCstr(root, "id");
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
static void blade_rpc_response_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
|
||||
{
|
||||
blade_rpc_response_t *brpcres = (blade_rpc_response_t *)ptr;
|
||||
|
||||
ks_assert(brpcres);
|
||||
|
||||
switch (action) {
|
||||
case KS_MPCL_ANNOUNCE:
|
||||
break;
|
||||
case KS_MPCL_TEARDOWN:
|
||||
ks_pool_free(brpcres->pool, (void **)&brpcres->session_id);
|
||||
blade_rpc_request_destroy(&brpcres->request);
|
||||
cJSON_Delete(brpcres->message);
|
||||
break;
|
||||
case KS_MPCL_DESTROY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_response_create(blade_rpc_response_t **brpcresP,
|
||||
blade_handle_t *bh,
|
||||
ks_pool_t *pool,
|
||||
const char *session_id,
|
||||
blade_rpc_request_t *brpcreq,
|
||||
cJSON *json)
|
||||
{
|
||||
blade_rpc_response_t *brpcres = NULL;
|
||||
|
||||
ks_assert(brpcresP);
|
||||
ks_assert(bh);
|
||||
ks_assert(pool);
|
||||
ks_assert(session_id);
|
||||
ks_assert(brpcreq);
|
||||
ks_assert(json);
|
||||
|
||||
brpcres = ks_pool_alloc(pool, sizeof(blade_rpc_response_t));
|
||||
brpcres->handle = bh;
|
||||
brpcres->pool = pool;
|
||||
brpcres->session_id = ks_pstrdup(pool, session_id);
|
||||
brpcres->request = brpcreq;
|
||||
brpcres->message = cJSON_Duplicate(json, 1);
|
||||
|
||||
ks_pool_set_cleanup(pool, brpcres, NULL, blade_rpc_response_cleanup);
|
||||
|
||||
*brpcresP = brpcres;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_response_destroy(blade_rpc_response_t **brpcresP)
|
||||
{
|
||||
blade_rpc_response_t *brpcres = NULL;
|
||||
|
||||
ks_assert(brpcresP);
|
||||
ks_assert(*brpcresP);
|
||||
|
||||
brpcres = *brpcresP;
|
||||
|
||||
ks_pool_free(brpcres->pool, brpcresP);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_response_raw_create(cJSON **json, cJSON **result, const char *id)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
cJSON *r = NULL;
|
||||
|
||||
ks_assert(json);
|
||||
ks_assert(id);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||
|
||||
cJSON_AddStringToObject(root, "id", id);
|
||||
|
||||
r = cJSON_CreateObject();
|
||||
cJSON_AddItemToObject(root, "result", r);
|
||||
|
||||
*json = root;
|
||||
if (result) *result = r;
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_handle_t *) blade_rpc_response_handle_get(blade_rpc_response_t *brpcres)
|
||||
{
|
||||
ks_assert(brpcres);
|
||||
return brpcres->handle;
|
||||
}
|
||||
|
||||
KS_DECLARE(const char *) blade_rpc_response_sessionid_get(blade_rpc_response_t *brpcres)
|
||||
{
|
||||
ks_assert(brpcres);
|
||||
return brpcres->session_id;
|
||||
}
|
||||
|
||||
KS_DECLARE(blade_rpc_request_t *) blade_rpc_response_request_get(blade_rpc_response_t *brpcres)
|
||||
{
|
||||
ks_assert(brpcres);
|
||||
return brpcres->request;
|
||||
}
|
||||
|
||||
KS_DECLARE(cJSON *) blade_rpc_response_message_get(blade_rpc_response_t *brpcres)
|
||||
{
|
||||
ks_assert(brpcres);
|
||||
return brpcres->message;
|
||||
}
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_error_raw_create(cJSON **json, cJSON **error, const char *id, int32_t code, const char *message)
|
||||
{
|
||||
cJSON *root = NULL;
|
||||
cJSON *e = NULL;
|
||||
|
||||
ks_assert(json);
|
||||
//ks_assert(id);
|
||||
ks_assert(message);
|
||||
|
||||
root = cJSON_CreateObject();
|
||||
|
||||
cJSON_AddStringToObject(root, "jsonrpc", "2.0");
|
||||
|
||||
if (id) cJSON_AddStringToObject(root, "id", id);
|
||||
|
||||
e = cJSON_CreateObject();
|
||||
cJSON_AddNumberToObject(e, "code", code);
|
||||
cJSON_AddStringToObject(e, "message", message);
|
||||
cJSON_AddItemToObject(root, "error", e);
|
||||
|
||||
*json = root;
|
||||
if (error) *error = e;
|
||||
|
||||
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:
|
||||
*/
|
|
@ -76,23 +76,9 @@ static void blade_session_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool
|
|||
blade_session_shutdown(bs);
|
||||
break;
|
||||
case KS_MPCL_DESTROY:
|
||||
|
||||
// @todo consider looking at supporting externally allocated memory entries that can have cleanup callbacks associated, but the memory is not freed from the pool, only linked as an external allocation for auto cleanup
|
||||
// which would allow calling something like ks_pool_set_cleanup(bs->properties, ...) and when the pool is destroyed, it can call a callback which handles calling cJSON_Delete, which is allocated externally
|
||||
cJSON_Delete(bs->properties);
|
||||
bs->properties = NULL;
|
||||
|
||||
// @todo remove this, it's just for posterity in debugging
|
||||
//bs->state_thread = NULL;
|
||||
bs->properties_lock = NULL;
|
||||
bs->receiving = NULL;
|
||||
bs->sending = NULL;
|
||||
bs->connection = NULL;
|
||||
bs->cond = NULL;
|
||||
bs->lock = NULL;
|
||||
|
||||
//ks_pool_free(bs->pool, &bs->id);
|
||||
bs->id = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -508,6 +494,8 @@ void *blade_session_state_thread(ks_thread_t *thread, void *data)
|
|||
// we can start stuffing any messages queued for output on the session straight to the connection right away, may need to only
|
||||
// do this when in session ready state but there may be implications of other states sending messages through the session
|
||||
while (blade_session_sending_pop(bs, &json) == KS_STATUS_SUCCESS && json) {
|
||||
// @todo short-circuit with blade_session_receiving_push on the same session if the message has responder-nodeid == requester-nodeid == local_nodeid
|
||||
// which would allow a system to send messages to itself, such as calling a protocolrpc immediately without bouncing upstream first
|
||||
blade_connection_sending_push(bc, json);
|
||||
cJSON_Delete(json);
|
||||
}
|
||||
|
@ -520,9 +508,7 @@ void *blade_session_state_thread(ks_thread_t *thread, void *data)
|
|||
|
||||
switch (state) {
|
||||
case BLADE_SESSION_STATE_STARTUP:
|
||||
// @todo this may occur from a reconnect, should have some way to identify it is a reconnected session until we hit RUN state at least
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) state startup\n", bs->id);
|
||||
blade_session_state_set(bs, BLADE_SESSION_STATE_RUN);
|
||||
blade_session_onstate_startup(bs);
|
||||
break;
|
||||
case BLADE_SESSION_STATE_SHUTDOWN:
|
||||
blade_session_onstate_shutdown(bs);
|
||||
|
@ -549,12 +535,21 @@ void *blade_session_state_thread(ks_thread_t *thread, void *data)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ks_status_t blade_session_onstate_startup(blade_session_t *bs)
|
||||
{
|
||||
ks_assert(bs);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) state startup\n", bs->id);
|
||||
blade_session_state_set(bs, BLADE_SESSION_STATE_RUN);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ks_status_t blade_session_onstate_shutdown(blade_session_t *bs)
|
||||
{
|
||||
ks_assert(bs);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) state shutdown\n", bs->id);
|
||||
|
||||
blade_session_state_set(bs, BLADE_SESSION_STATE_CLEANUP);
|
||||
|
||||
if (bs->connection) {
|
||||
|
@ -565,7 +560,7 @@ ks_status_t blade_session_onstate_shutdown(blade_session_t *bs)
|
|||
}
|
||||
}
|
||||
|
||||
// @note wait for the connection to disconnect before we resume session cleanup
|
||||
// wait for the connection to disconnect before we resume session cleanup
|
||||
while (bs->connection) ks_sleep(100);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
|
@ -577,28 +572,18 @@ ks_status_t blade_session_onstate_run(blade_session_t *bs)
|
|||
|
||||
ks_assert(bs);
|
||||
|
||||
//ks_log(KS_LOG_DEBUG, "Session (%s) state run\n", bs->id);
|
||||
|
||||
// @todo for now only process messages if there is a connection available
|
||||
if (bs->connection) {
|
||||
// @todo may only want to pop once per call to give sending a chance to keep up
|
||||
while (blade_session_receiving_pop(bs, &json) == KS_STATUS_SUCCESS && json) {
|
||||
// @todo all messages will pass through the local jsonrpc method handlers, but each needs to determine if the
|
||||
// message is destined for the local node, and if not then each handler can determine how routing occurs as
|
||||
// they differ, especially when it comes to the announcing of identities and propagation of multicast events
|
||||
blade_session_process(bs, json);
|
||||
cJSON_Delete(json);
|
||||
}
|
||||
while (bs->connection && blade_session_receiving_pop(bs, &json) == KS_STATUS_SUCCESS && json) {
|
||||
blade_session_process(bs, json);
|
||||
cJSON_Delete(json);
|
||||
}
|
||||
|
||||
//ks_sleep_ms(1);
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, blade_jsonrpc_response_callback_t callback)
|
||||
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, blade_rpc_response_callback_t callback, void *data)
|
||||
{
|
||||
blade_jsonrpc_request_t *bjsonrpcreq = NULL;
|
||||
blade_rpc_request_t *brpcreq = NULL;
|
||||
const char *method = NULL;
|
||||
const char *id = NULL;
|
||||
|
||||
|
@ -615,17 +600,18 @@ KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, bla
|
|||
// 1) Sending a request (client: method caller or consumer)
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) sending request (%s) for %s\n", bs->id, id, method);
|
||||
|
||||
blade_jsonrpc_request_create(&bjsonrpcreq, bs->handle, blade_handle_pool_get(bs->handle), bs->id, json, callback);
|
||||
ks_assert(bjsonrpcreq);
|
||||
blade_rpc_request_create(&brpcreq, bs->handle, blade_handle_pool_get(bs->handle), bs->id, json, callback, data);
|
||||
ks_assert(brpcreq);
|
||||
|
||||
// @todo set request TTL and figure out when requests are checked for expiration (separate thread in the handle?)
|
||||
blade_handle_requests_add(bjsonrpcreq);
|
||||
blade_handle_requests_add(brpcreq);
|
||||
} else {
|
||||
// @note This is scenario 3
|
||||
// 3) Sending a response or error (server: method callee or provider)
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) sending response (%s)\n", bs->id, id);
|
||||
}
|
||||
|
||||
//blade_session_sending_push(bs, json);
|
||||
if (!bs->connection) {
|
||||
blade_session_sending_push(bs, json);
|
||||
} else {
|
||||
|
@ -644,8 +630,8 @@ KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, bla
|
|||
ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
||||
{
|
||||
blade_handle_t *bh = NULL;
|
||||
blade_jsonrpc_request_t *bjsonrpcreq = NULL;
|
||||
blade_jsonrpc_response_t *bjsonrpcres = NULL;
|
||||
blade_rpc_request_t *brpcreq = NULL;
|
||||
blade_rpc_response_t *brpcres = NULL;
|
||||
const char *jsonrpc = NULL;
|
||||
const char *id = NULL;
|
||||
const char *method = NULL;
|
||||
|
@ -680,8 +666,8 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
|||
if (method) {
|
||||
// @note This is scenario 2
|
||||
// 2) Receiving a request (server: method callee or provider)
|
||||
blade_jsonrpc_t *bjsonrpc = NULL;
|
||||
blade_jsonrpc_request_callback_t callback = NULL;
|
||||
blade_rpc_t *brpc = NULL;
|
||||
blade_rpc_request_callback_t callback = NULL;
|
||||
cJSON *params = NULL;
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) receiving request (%s) for %s\n", bs->id, id, method);
|
||||
|
@ -700,13 +686,13 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
|||
cJSON *res_error = NULL;
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) request (%s => %s) but upstream session unavailable\n", blade_session_id_get(bs), params_requester_nodeid, params_responder_nodeid);
|
||||
blade_jsonrpc_error_raw_create(&res, &res_error, id, -32603, "Upstream session unavailable");
|
||||
blade_rpc_error_raw_create(&res, &res_error, id, -32603, "Upstream session unavailable");
|
||||
|
||||
// needed in case this error must propagate further than the session which sent it
|
||||
cJSON_AddStringToObject(res_error, "requester-nodeid", params_requester_nodeid);
|
||||
cJSON_AddStringToObject(res_error, "responder-nodeid", params_responder_nodeid); // @todo responder-nodeid should become the local_nodeid to inform of which node actually responded
|
||||
|
||||
blade_session_send(bs, res, NULL);
|
||||
blade_session_send(bs, res, NULL, NULL);
|
||||
return KS_STATUS_DISCONNECTED;
|
||||
}
|
||||
}
|
||||
|
@ -716,7 +702,7 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
|||
}
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) request (%s => %s) routing (%s)\n", blade_session_id_get(bs), params_requester_nodeid, params_responder_nodeid, blade_session_id_get(bs_router));
|
||||
blade_session_send(bs_router, json, NULL);
|
||||
blade_session_send(bs_router, json, NULL, NULL);
|
||||
blade_session_read_unlock(bs_router);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
|
@ -724,26 +710,26 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
|||
}
|
||||
|
||||
// reach here if the request was not captured for routing, this SHOULD always mean the message is to be processed by local handlers
|
||||
bjsonrpc = blade_handle_jsonrpc_lookup(bs->handle, method);
|
||||
brpc = blade_handle_corerpc_lookup(bs->handle, method);
|
||||
|
||||
if (!bjsonrpc) {
|
||||
ks_log(KS_LOG_DEBUG, "Received unknown jsonrpc method %s\n", method);
|
||||
if (!brpc) {
|
||||
ks_log(KS_LOG_DEBUG, "Received unknown rpc method %s\n", method);
|
||||
// @todo send error response, code = -32601 (method not found)
|
||||
return KS_STATUS_FAIL;
|
||||
}
|
||||
callback = blade_jsonrpc_callback_get(bjsonrpc);
|
||||
callback = blade_rpc_callback_get(brpc);
|
||||
ks_assert(callback);
|
||||
|
||||
blade_jsonrpc_request_create(&bjsonrpcreq, bs->handle, blade_handle_pool_get(bs->handle), bs->id, json, NULL);
|
||||
ks_assert(bjsonrpcreq);
|
||||
blade_rpc_request_create(&brpcreq, bs->handle, blade_handle_pool_get(bs->handle), bs->id, json, NULL, NULL);
|
||||
ks_assert(brpcreq);
|
||||
|
||||
disconnect = callback(bjsonrpcreq, blade_jsonrpc_callback_data_get(bjsonrpc));
|
||||
disconnect = callback(brpcreq, blade_rpc_callback_data_get(brpc));
|
||||
|
||||
blade_jsonrpc_request_destroy(&bjsonrpcreq);
|
||||
blade_rpc_request_destroy(&brpcreq);
|
||||
} else {
|
||||
// @note This is scenario 4
|
||||
// 4) Receiving a response or error (client: method caller or consumer)
|
||||
blade_jsonrpc_response_callback_t callback = NULL;
|
||||
blade_rpc_response_callback_t callback = NULL;
|
||||
cJSON *error = NULL;
|
||||
cJSON *result = NULL;
|
||||
cJSON *object = NULL;
|
||||
|
@ -773,29 +759,29 @@ ks_status_t blade_session_process(blade_session_t *bs, cJSON *json)
|
|||
}
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) response (%s <= %s) routing (%s)\n", blade_session_id_get(bs), object_requester_nodeid, object_responder_nodeid, blade_session_id_get(bs_router));
|
||||
blade_session_send(bs_router, json, NULL);
|
||||
blade_session_send(bs_router, json, NULL, NULL);
|
||||
blade_session_read_unlock(bs_router);
|
||||
|
||||
return KS_STATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
bjsonrpcreq = blade_handle_requests_lookup(bs->handle, id);
|
||||
if (!bjsonrpcreq) {
|
||||
brpcreq = blade_handle_requests_lookup(bs->handle, id);
|
||||
if (!brpcreq) {
|
||||
// @todo hangup session entirely?
|
||||
return KS_STATUS_FAIL;
|
||||
}
|
||||
blade_handle_requests_remove(bjsonrpcreq);
|
||||
blade_handle_requests_remove(brpcreq);
|
||||
|
||||
callback = blade_jsonrpc_request_callback_get(bjsonrpcreq);
|
||||
callback = blade_rpc_request_callback_get(brpcreq);
|
||||
ks_assert(callback);
|
||||
|
||||
blade_jsonrpc_response_create(&bjsonrpcres, bs->handle, bs->pool, bs->id, bjsonrpcreq, json);
|
||||
ks_assert(bjsonrpcres);
|
||||
blade_rpc_response_create(&brpcres, bs->handle, bs->pool, bs->id, brpcreq, json);
|
||||
ks_assert(brpcres);
|
||||
|
||||
disconnect = callback(bjsonrpcres);
|
||||
disconnect = callback(brpcres, blade_rpc_request_callback_data_get(brpcreq));
|
||||
|
||||
blade_jsonrpc_response_destroy(&bjsonrpcres);
|
||||
blade_rpc_response_destroy(&brpcres);
|
||||
}
|
||||
|
||||
if (disconnect) {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -687,7 +687,7 @@ ks_status_t blade_transport_wss_onreceive(blade_connection_t *bc, cJSON **json)
|
|||
return blade_transport_wss_link_read(btwssl, json);
|
||||
}
|
||||
|
||||
ks_status_t blade_transport_wss_jsonrpc_error_send(blade_connection_t *bc, const char *id, int32_t code, const char *message)
|
||||
ks_status_t blade_transport_wss_rpc_error_send(blade_connection_t *bc, const char *id, int32_t code, const char *message)
|
||||
{
|
||||
ks_status_t ret = KS_STATUS_SUCCESS;
|
||||
blade_transport_wss_link_t *btwssl = NULL;
|
||||
|
@ -699,7 +699,7 @@ ks_status_t blade_transport_wss_jsonrpc_error_send(blade_connection_t *bc, const
|
|||
|
||||
btwssl = (blade_transport_wss_link_t *)blade_connection_transport_get(bc);
|
||||
|
||||
blade_jsonrpc_error_raw_create(&json, NULL, id, code, message);
|
||||
blade_rpc_error_raw_create(&json, NULL, id, code, message);
|
||||
|
||||
if (blade_transport_wss_link_write(btwssl, json) != KS_STATUS_SUCCESS) {
|
||||
ks_log(KS_LOG_DEBUG, "Failed to write error message\n");
|
||||
|
@ -761,18 +761,18 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
|
|||
|
||||
if (!json_req) {
|
||||
ks_log(KS_LOG_DEBUG, "Failed to receive message before timeout\n");
|
||||
blade_transport_wss_jsonrpc_error_send(bc, NULL, -32600, "Timeout while expecting request");
|
||||
blade_transport_wss_rpc_error_send(bc, NULL, -32600, "Timeout while expecting request");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
||||
// @todo start here for a reusable handler for "blade.connect" request jsonrpc method within transport implementations,
|
||||
// @todo start here for a reusable handler for "blade.connect" request rpc method within transport implementations,
|
||||
// output 2 parameters for response and error, if an error occurs, send it, otherwise send the response
|
||||
|
||||
jsonrpc = cJSON_GetObjectCstr(json_req, "jsonrpc"); // @todo check for definitions of these keys and fixed values
|
||||
if (!jsonrpc || strcmp(jsonrpc, "2.0")) {
|
||||
ks_log(KS_LOG_DEBUG, "Received message is not the expected protocol\n");
|
||||
blade_transport_wss_jsonrpc_error_send(bc, NULL, -32600, "Invalid request, missing 'jsonrpc' field");
|
||||
blade_transport_wss_rpc_error_send(bc, NULL, -32600, "Invalid request, missing 'jsonrpc' field");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
@ -780,7 +780,7 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
|
|||
id = cJSON_GetObjectCstr(json_req, "id");
|
||||
if (!id) {
|
||||
ks_log(KS_LOG_DEBUG, "Received message is missing 'id'\n");
|
||||
blade_transport_wss_jsonrpc_error_send(bc, NULL, -32600, "Invalid request, missing 'id' field");
|
||||
blade_transport_wss_rpc_error_send(bc, NULL, -32600, "Invalid request, missing 'id' field");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
@ -788,7 +788,7 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
|
|||
method = cJSON_GetObjectCstr(json_req, "method");
|
||||
if (!method || strcasecmp(method, "blade.connect")) {
|
||||
ks_log(KS_LOG_DEBUG, "Received message is missing 'method' or is an unexpected method\n");
|
||||
blade_transport_wss_jsonrpc_error_send(bc, id, -32601, "Missing or unexpected 'method' field");
|
||||
blade_transport_wss_rpc_error_send(bc, id, -32601, "Missing or unexpected 'method' field");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
@ -826,7 +826,7 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
|
|||
|
||||
if (blade_session_startup(bs) != KS_STATUS_SUCCESS) {
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) startup failed\n", nodeid);
|
||||
blade_transport_wss_jsonrpc_error_send(bc, id, -32603, "Internal error, session could not be started");
|
||||
blade_transport_wss_rpc_error_send(bc, id, -32603, "Internal error, session could not be started");
|
||||
blade_session_read_unlock(bs);
|
||||
blade_session_destroy(&bs);
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
|
@ -863,7 +863,7 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
|
|||
ks_hash_read_unlock(realms);
|
||||
}
|
||||
|
||||
blade_jsonrpc_response_raw_create(&json_res, &json_result, id);
|
||||
blade_rpc_response_raw_create(&json_res, &json_result, id);
|
||||
ks_assert(json_res);
|
||||
|
||||
cJSON_AddStringToObject(json_result, "nodeid", nodeid);
|
||||
|
@ -872,7 +872,7 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_inbound(blade_
|
|||
master_nodeid = blade_handle_master_nodeid_copy(bh, pool);
|
||||
if (!master_nodeid) {
|
||||
ks_log(KS_LOG_DEBUG, "Master nodeid unavailable\n");
|
||||
blade_transport_wss_jsonrpc_error_send(bc, id, -32602, "Master nodeid unavailable");
|
||||
blade_transport_wss_rpc_error_send(bc, id, -32602, "Master nodeid unavailable");
|
||||
ret = BLADE_CONNECTION_STATE_HOOK_DISCONNECT;
|
||||
goto done;
|
||||
}
|
||||
|
@ -961,7 +961,7 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_outbound(blade
|
|||
goto done;
|
||||
}
|
||||
|
||||
blade_jsonrpc_request_raw_create(pool, &json_req, &json_params, &mid, "blade.connect");
|
||||
blade_rpc_request_raw_create(pool, &json_req, &json_params, &mid, "blade.connect");
|
||||
ks_assert(json_req);
|
||||
|
||||
if (btwssl->session_id) cJSON_AddStringToObject(json_params, "session-id", btwssl->session_id);
|
||||
|
@ -988,7 +988,7 @@ blade_connection_state_hook_t blade_transport_wss_onstate_startup_outbound(blade
|
|||
goto done;
|
||||
}
|
||||
|
||||
// @todo start here for a reusable handler for "blade.connect" response jsonrpc method within transport implementations
|
||||
// @todo start here for a reusable handler for "blade.connect" response rpc method within transport implementations
|
||||
|
||||
jsonrpc = cJSON_GetObjectCstr(json_res, "jsonrpc"); // @todo check for definitions of these keys and fixed values
|
||||
if (!jsonrpc || strcmp(jsonrpc, "2.0")) {
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
#include "blade_stack.h"
|
||||
#include "blade_identity.h"
|
||||
#include "blade_transport.h"
|
||||
#include "blade_jsonrpc.h"
|
||||
#include "blade_rpc.h"
|
||||
#include "blade_connection.h"
|
||||
#include "blade_session.h"
|
||||
#include "blade_protocol.h"
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2017, Shane Bryldt
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* * Neither the name of the original author; nor the names of any contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _BLADE_JSONRPC_H_
|
||||
#define _BLADE_JSONRPC_H_
|
||||
#include <blade.h>
|
||||
|
||||
KS_BEGIN_EXTERN_C
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_create(blade_jsonrpc_t **bjsonrpcP, blade_handle_t *bh, const char *method, blade_jsonrpc_request_callback_t callback, void *callback_data);
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_destroy(blade_jsonrpc_t **bjsonrpcP);
|
||||
KS_DECLARE(blade_handle_t *) blade_jsonrpc_handle_get(blade_jsonrpc_t *bjsonrpc);
|
||||
KS_DECLARE(const char *) blade_jsonrpc_method_get(blade_jsonrpc_t *bjsonrpc);
|
||||
KS_DECLARE(blade_jsonrpc_request_callback_t) blade_jsonrpc_callback_get(blade_jsonrpc_t *bjsonrpc);
|
||||
KS_DECLARE(void *) blade_jsonrpc_callback_data_get(blade_jsonrpc_t *bjsonrpc);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_request_create(blade_jsonrpc_request_t **bjsonrpcreqP,
|
||||
blade_handle_t *bh,
|
||||
ks_pool_t *pool,
|
||||
const char *session_id,
|
||||
cJSON *json,
|
||||
blade_jsonrpc_response_callback_t callback);
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_request_destroy(blade_jsonrpc_request_t **bjsonrpcreqP);
|
||||
KS_DECLARE(blade_handle_t *) blade_jsonrpc_request_handle_get(blade_jsonrpc_request_t *bjsonrpcreq);
|
||||
KS_DECLARE(const char *) blade_jsonrpc_request_sessionid_get(blade_jsonrpc_request_t *bjsonrpcreq);
|
||||
KS_DECLARE(cJSON *) blade_jsonrpc_request_message_get(blade_jsonrpc_request_t *bjsonrpcreq);
|
||||
KS_DECLARE(const char *) blade_jsonrpc_request_messageid_get(blade_jsonrpc_request_t *bjsonrpcreq);
|
||||
KS_DECLARE(blade_jsonrpc_response_callback_t) blade_jsonrpc_request_callback_get(blade_jsonrpc_request_t *bjsonrpcreq);
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_request_raw_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_response_create(blade_jsonrpc_response_t **bjsonrpcresP,
|
||||
blade_handle_t *bh,
|
||||
ks_pool_t *pool,
|
||||
const char *session_id,
|
||||
blade_jsonrpc_request_t *bjsonrpcreq,
|
||||
cJSON *json);
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_response_destroy(blade_jsonrpc_response_t **bjsonrpcresP);
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_response_raw_create(cJSON **json, cJSON **result, const char *id);
|
||||
KS_DECLARE(blade_handle_t *) blade_jsonrpc_response_handle_get(blade_jsonrpc_response_t *bjsonrpcres);
|
||||
KS_DECLARE(const char *) blade_jsonrpc_response_sessionid_get(blade_jsonrpc_response_t *bjsonrpcres);
|
||||
KS_DECLARE(blade_jsonrpc_request_t *) blade_jsonrpc_response_request_get(blade_jsonrpc_response_t *bjsonrpcres);
|
||||
KS_DECLARE(cJSON *) blade_jsonrpc_response_message_get(blade_jsonrpc_response_t *bjsonrpcres);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_jsonrpc_error_raw_create(cJSON **json, cJSON **error, const char *id, int32_t code, const char *message);
|
||||
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:
|
||||
*/
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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_RPC_H_
|
||||
#define _BLADE_RPC_H_
|
||||
#include <blade.h>
|
||||
|
||||
KS_BEGIN_EXTERN_C
|
||||
KS_DECLARE(ks_status_t) blade_rpc_create(blade_rpc_t **brpcP, blade_handle_t *bh, const char *method, const char *protocol, const char *realm, blade_rpc_request_callback_t callback, void *callback_data);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_destroy(blade_rpc_t **brpcP);
|
||||
KS_DECLARE(blade_handle_t *) blade_rpc_handle_get(blade_rpc_t *brpc);
|
||||
KS_DECLARE(const char *) blade_rpc_method_get(blade_rpc_t *brpc);
|
||||
KS_DECLARE(const char *) blade_rpc_protocol_get(blade_rpc_t *brpc);
|
||||
KS_DECLARE(const char *) blade_rpc_realm_get(blade_rpc_t *brpc);
|
||||
KS_DECLARE(blade_rpc_request_callback_t) blade_rpc_callback_get(blade_rpc_t *brpc);
|
||||
KS_DECLARE(void *) blade_rpc_callback_data_get(blade_rpc_t *brpc);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_request_create(blade_rpc_request_t **brpcreqP,
|
||||
blade_handle_t *bh,
|
||||
ks_pool_t *pool,
|
||||
const char *session_id,
|
||||
cJSON *json,
|
||||
blade_rpc_response_callback_t callback,
|
||||
void *data);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_request_destroy(blade_rpc_request_t **brpcreqP);
|
||||
KS_DECLARE(blade_handle_t *) blade_rpc_request_handle_get(blade_rpc_request_t *brpcreq);
|
||||
KS_DECLARE(const char *) blade_rpc_request_sessionid_get(blade_rpc_request_t *brpcreq);
|
||||
KS_DECLARE(cJSON *) blade_rpc_request_message_get(blade_rpc_request_t *brpcreq);
|
||||
KS_DECLARE(const char *) blade_rpc_request_messageid_get(blade_rpc_request_t *brpcreq);
|
||||
KS_DECLARE(blade_rpc_response_callback_t) blade_rpc_request_callback_get(blade_rpc_request_t *brpcreq);
|
||||
KS_DECLARE(void *) blade_rpc_request_callback_data_get(blade_rpc_request_t *brpcreq);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_request_raw_create(ks_pool_t *pool, cJSON **json, cJSON **params, const char **id, const char *method);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_response_create(blade_rpc_response_t **brpcresP,
|
||||
blade_handle_t *bh,
|
||||
ks_pool_t *pool,
|
||||
const char *session_id,
|
||||
blade_rpc_request_t *brpcreq,
|
||||
cJSON *json);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_response_destroy(blade_rpc_response_t **brpcresP);
|
||||
KS_DECLARE(ks_status_t) blade_rpc_response_raw_create(cJSON **json, cJSON **result, const char *id);
|
||||
KS_DECLARE(blade_handle_t *) blade_rpc_response_handle_get(blade_rpc_response_t *brpcres);
|
||||
KS_DECLARE(const char *) blade_rpc_response_sessionid_get(blade_rpc_response_t *brpcres);
|
||||
KS_DECLARE(blade_rpc_request_t *) blade_rpc_response_request_get(blade_rpc_response_t *brpcres);
|
||||
KS_DECLARE(cJSON *) blade_rpc_response_message_get(blade_rpc_response_t *brpcres);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_rpc_error_raw_create(cJSON **json, cJSON **error, const char *id, int32_t code, const char *message);
|
||||
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:
|
||||
*/
|
|
@ -62,7 +62,7 @@ KS_DECLARE(void) blade_session_hangup(blade_session_t *bs);
|
|||
KS_DECLARE(ks_bool_t) blade_session_terminating(blade_session_t *bs);
|
||||
KS_DECLARE(const char *) blade_session_connection_get(blade_session_t *bs);
|
||||
KS_DECLARE(ks_status_t) blade_session_connection_set(blade_session_t *bs, const char *id);
|
||||
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, blade_jsonrpc_response_callback_t callback);
|
||||
KS_DECLARE(ks_status_t) blade_session_send(blade_session_t *bs, cJSON *json, blade_rpc_response_callback_t callback, void *data);
|
||||
KS_DECLARE(ks_status_t) blade_session_sending_push(blade_session_t *bs, cJSON *json);
|
||||
KS_DECLARE(ks_status_t) blade_session_sending_pop(blade_session_t *bs, cJSON **json);
|
||||
KS_DECLARE(ks_status_t) blade_session_receiving_push(blade_session_t *bs, cJSON *json);
|
||||
|
|
|
@ -66,13 +66,17 @@ KS_DECLARE(blade_session_t *) blade_handle_route_lookup(blade_handle_t *bh, cons
|
|||
KS_DECLARE(ks_status_t) blade_handle_transport_register(blade_transport_t *bt);
|
||||
KS_DECLARE(ks_status_t) blade_handle_transport_unregister(blade_transport_t *bt);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_jsonrpc_register(blade_jsonrpc_t *bjsonrpc);
|
||||
KS_DECLARE(ks_status_t) blade_handle_jsonrpc_unregister(blade_jsonrpc_t *bjsonrpc);
|
||||
KS_DECLARE(blade_jsonrpc_t *) blade_handle_jsonrpc_lookup(blade_handle_t *bh, const char *method);
|
||||
KS_DECLARE(ks_status_t) blade_handle_corerpc_register(blade_rpc_t *brpc);
|
||||
KS_DECLARE(ks_status_t) blade_handle_corerpc_unregister(blade_rpc_t *brpc);
|
||||
KS_DECLARE(blade_rpc_t *) blade_handle_corerpc_lookup(blade_handle_t *bh, const char *method);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_requests_add(blade_jsonrpc_request_t *bjsonrpcreq);
|
||||
KS_DECLARE(ks_status_t) blade_handle_requests_remove(blade_jsonrpc_request_t *bjsonrpcreq);
|
||||
KS_DECLARE(blade_jsonrpc_request_t *) blade_handle_requests_lookup(blade_handle_t *bh, const char *id);
|
||||
KS_DECLARE(ks_status_t) blade_handle_requests_add(blade_rpc_request_t *brpcreq);
|
||||
KS_DECLARE(ks_status_t) blade_handle_requests_remove(blade_rpc_request_t *brpcreq);
|
||||
KS_DECLARE(blade_rpc_request_t *) blade_handle_requests_lookup(blade_handle_t *bh, const char *id);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_protocolrpc_register(blade_rpc_t *brpc);
|
||||
KS_DECLARE(ks_status_t) blade_handle_protocolrpc_unregister(blade_rpc_t *brpc);
|
||||
KS_DECLARE(blade_rpc_t *) blade_handle_protocolrpc_lookup(blade_handle_t *bh, const char *method, const char *protocol, const char *realm);
|
||||
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_handle_connect(blade_handle_t *bh, blade_connection_t **bcP, blade_identity_t *target, const char *session_id);
|
||||
|
@ -91,8 +95,15 @@ KS_DECLARE(ks_status_t) blade_handle_session_state_callback_register(blade_handl
|
|||
KS_DECLARE(ks_status_t) blade_handle_session_state_callback_unregister(blade_handle_t *bh, const char *id);
|
||||
KS_DECLARE(void) blade_handle_session_state_callbacks_execute(blade_session_t *bs, blade_session_state_condition_t condition);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_protocol_publish(blade_handle_t *bh, const char *name, const char *realm);
|
||||
KS_DECLARE(ks_status_t) blade_protocol_locate(blade_handle_t *bh, const char *name, const char *realm);
|
||||
KS_DECLARE(ks_status_t) blade_protocol_publish(blade_handle_t *bh, const char *name, const char *realm, blade_rpc_response_callback_t callback, void *data);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_protocol_locate(blade_handle_t *bh, const char *name, const char *realm, blade_rpc_response_callback_t callback, void *data);
|
||||
|
||||
KS_DECLARE(ks_status_t) blade_protocol_execute(blade_handle_t *bh, const char *nodeid, const char *method, const char *protocol, const char *realm, cJSON *params, blade_rpc_response_callback_t callback, void *data);
|
||||
KS_DECLARE(cJSON *) blade_protocol_execute_request_params_get(blade_rpc_request_t *brpcreq);
|
||||
KS_DECLARE(cJSON *) blade_protocol_execute_response_result_get(blade_rpc_response_t *brpcres);
|
||||
KS_DECLARE(void) blade_protocol_execute_response_send(blade_rpc_request_t *brpcreq, cJSON *result);
|
||||
|
||||
KS_END_EXTERN_C
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,9 +42,9 @@ typedef struct blade_handle_s blade_handle_t;
|
|||
typedef struct blade_identity_s blade_identity_t;
|
||||
typedef struct blade_transport_s blade_transport_t;
|
||||
typedef struct blade_transport_callbacks_s blade_transport_callbacks_t;
|
||||
typedef struct blade_jsonrpc_s blade_jsonrpc_t;
|
||||
typedef struct blade_jsonrpc_request_s blade_jsonrpc_request_t;
|
||||
typedef struct blade_jsonrpc_response_s blade_jsonrpc_response_t;
|
||||
typedef struct blade_rpc_s blade_rpc_t;
|
||||
typedef struct blade_rpc_request_s blade_rpc_request_t;
|
||||
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;
|
||||
|
@ -53,8 +53,8 @@ typedef struct blade_protocol_realm_s blade_protocol_realm_t;
|
|||
typedef struct blade_protocol_method_s blade_protocol_method_t;
|
||||
|
||||
|
||||
typedef ks_bool_t (*blade_jsonrpc_request_callback_t)(blade_jsonrpc_request_t *breq, void *data);
|
||||
typedef ks_bool_t (*blade_jsonrpc_response_callback_t)(blade_jsonrpc_response_t *bres);
|
||||
typedef ks_bool_t (*blade_rpc_request_callback_t)(blade_rpc_request_t *brpcreq, void *data);
|
||||
typedef ks_bool_t (*blade_rpc_response_callback_t)(blade_rpc_response_t *brpcres, void *data);
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
|
|
@ -16,20 +16,98 @@ struct command_def_s {
|
|||
};
|
||||
|
||||
void command_quit(blade_handle_t *bh, char *args);
|
||||
void command_connect(blade_handle_t *bh, char *args);
|
||||
//void command_chat(blade_handle_t *bh, char *args);
|
||||
void command_execute(blade_handle_t *bh, char *args);
|
||||
|
||||
static const struct command_def_s command_defs[] = {
|
||||
{ "quit", command_quit },
|
||||
{ "connect", command_connect },
|
||||
// { "chat", command_chat },
|
||||
{ "execute", command_execute },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
//ks_bool_t on_blade_chat_join_response(blade_response_t *bres);
|
||||
//ks_bool_t on_blade_chat_message_event(blade_event_t *bev);
|
||||
//void on_blade_session_state_callback(blade_session_t *bs, blade_session_state_condition_t condition, void *data);
|
||||
ks_bool_t test_echo_response_handler(blade_rpc_response_t *brpcres, void *data)
|
||||
{
|
||||
blade_handle_t *bh = NULL;
|
||||
blade_session_t *bs = NULL;
|
||||
cJSON *result = NULL;
|
||||
const char *text = NULL;
|
||||
|
||||
ks_assert(brpcres);
|
||||
|
||||
bh = blade_rpc_response_handle_get(brpcres);
|
||||
ks_assert(bh);
|
||||
|
||||
bs = blade_handle_sessions_lookup(bh, blade_rpc_response_sessionid_get(brpcres));
|
||||
ks_assert(bs);
|
||||
|
||||
result = blade_protocol_execute_response_result_get(brpcres);
|
||||
ks_assert(result);
|
||||
|
||||
text = cJSON_GetObjectCstr(result, "text");
|
||||
ks_assert(text);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) test.echo response processing\n", blade_session_id_get(bs));
|
||||
|
||||
blade_session_read_unlock(bs);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) test.echo: %s\n", blade_session_id_get(bs), text);
|
||||
|
||||
return KS_FALSE;
|
||||
}
|
||||
|
||||
ks_bool_t blade_locate_response_handler(blade_rpc_response_t *brpcres, void *data)
|
||||
{
|
||||
blade_handle_t *bh = NULL;
|
||||
blade_session_t *bs = NULL;
|
||||
const char *nodeid = NULL;
|
||||
cJSON *res = NULL;
|
||||
cJSON *res_result = NULL;
|
||||
cJSON *res_result_providers = NULL;
|
||||
const char *res_result_protocol = NULL;
|
||||
const char *res_result_realm = NULL;
|
||||
cJSON *params = NULL;
|
||||
|
||||
ks_assert(brpcres);
|
||||
|
||||
bh = blade_rpc_response_handle_get(brpcres);
|
||||
ks_assert(bh);
|
||||
|
||||
bs = blade_handle_sessions_lookup(bh, blade_rpc_response_sessionid_get(brpcres));
|
||||
ks_assert(bs);
|
||||
|
||||
res = blade_rpc_response_message_get(brpcres);
|
||||
ks_assert(res);
|
||||
|
||||
res_result = cJSON_GetObjectItem(res, "result");
|
||||
ks_assert(res_result);
|
||||
|
||||
res_result_protocol = cJSON_GetObjectCstr(res_result, "protocol");
|
||||
ks_assert(res_result_protocol);
|
||||
|
||||
res_result_realm = cJSON_GetObjectCstr(res_result, "realm");
|
||||
ks_assert(res_result_realm);
|
||||
|
||||
res_result_providers = cJSON_GetObjectItem(res_result, "providers");
|
||||
ks_assert(res_result_providers);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) blade.locate response processing\n", blade_session_id_get(bs));
|
||||
|
||||
for (int index = 0; index < cJSON_GetArraySize(res_result_providers); ++index) {
|
||||
cJSON *elem = cJSON_GetArrayItem(res_result_providers, index);
|
||||
if (elem->type == cJSON_String) {
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) blade.locate (%s@%s) provider (%s)\n", blade_session_id_get(bs), res_result_protocol, res_result_realm, elem->valuestring);
|
||||
nodeid = elem->valuestring;
|
||||
}
|
||||
}
|
||||
|
||||
blade_session_read_unlock(bs);
|
||||
|
||||
params = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(params, "text", "hello world!");
|
||||
blade_protocol_execute(bh, nodeid, "test.echo", res_result_protocol, res_result_realm, params, test_echo_response_handler, NULL);
|
||||
|
||||
return KS_FALSE;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
@ -71,9 +149,6 @@ int main(int argc, char **argv)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
//blade_handle_event_register(bh, "blade.chat.message", on_blade_chat_message_event);
|
||||
//blade_handle_session_state_callback_register(bh, NULL, on_blade_session_state_callback, &session_state_callback_id);
|
||||
|
||||
if (autoconnect) {
|
||||
blade_connection_t *bc = NULL;
|
||||
blade_identity_t *target = NULL;
|
||||
|
@ -85,13 +160,9 @@ int main(int argc, char **argv)
|
|||
blade_identity_destroy(&target);
|
||||
|
||||
ks_sleep_ms(5000);
|
||||
|
||||
blade_protocol_publish(bh, "test", "mydomain.com");
|
||||
|
||||
ks_sleep_ms(5000);
|
||||
} else loop(bh);
|
||||
|
||||
//blade_handle_session_state_callback_unregister(bh, session_state_callback_id);
|
||||
}
|
||||
|
||||
loop(bh);
|
||||
|
||||
blade_handle_destroy(&bh);
|
||||
|
||||
|
@ -102,38 +173,6 @@ int main(int argc, char **argv)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//ks_bool_t on_blade_chat_message_event(blade_event_t *bev)
|
||||
//{
|
||||
// cJSON *res = NULL;
|
||||
// const char *from = NULL;
|
||||
// const char *message = NULL;
|
||||
//
|
||||
// ks_assert(bev);
|
||||
//
|
||||
// res = cJSON_GetObjectItem(bev->message, "result");
|
||||
// from = cJSON_GetObjectCstr(res, "from");
|
||||
// message = cJSON_GetObjectCstr(res, "message");
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Received Chat Message Event: (%s) %s\n", from, message);
|
||||
//
|
||||
// return KS_FALSE;
|
||||
//}
|
||||
//
|
||||
//void on_blade_session_state_callback(blade_session_t *bs, blade_session_state_condition_t condition, void *data)
|
||||
//{
|
||||
// blade_session_state_t state = blade_session_state_get(bs);
|
||||
//
|
||||
// if (condition == BLADE_SESSION_STATE_CONDITION_PRE) {
|
||||
// ks_log(KS_LOG_DEBUG, "Blade Session State Changed: %s, %d\n", blade_session_id_get(bs), state);
|
||||
// if (state == BLADE_SESSION_STATE_READY) {
|
||||
// cJSON *req = NULL;
|
||||
// blade_jsonrpc_request_raw_create(blade_handle_pool_get(blade_session_handle_get(bs)), &req, NULL, NULL, "blade.chat.join");
|
||||
// blade_session_send(bs, req, on_blade_chat_join_response);
|
||||
// cJSON_Delete(req);
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
void loop(blade_handle_t *bh)
|
||||
{
|
||||
char buf[CONSOLE_INPUT_MAX];
|
||||
|
@ -199,92 +238,21 @@ void command_quit(blade_handle_t *bh, char *args)
|
|||
g_shutdown = KS_TRUE;
|
||||
}
|
||||
|
||||
void command_connect(blade_handle_t *bh, char *args)
|
||||
void command_execute(blade_handle_t *bh, char *args)
|
||||
{
|
||||
blade_connection_t *bc = NULL;
|
||||
blade_identity_t *target = NULL;
|
||||
|
||||
ks_assert(bh);
|
||||
ks_assert(args);
|
||||
|
||||
blade_identity_create(&target, blade_handle_pool_get(bh));
|
||||
|
||||
if (blade_identity_parse(target, args) == KS_STATUS_SUCCESS) blade_handle_connect(bh, &bc, target, NULL);
|
||||
|
||||
blade_identity_destroy(&target);
|
||||
blade_protocol_locate(bh, "test", "mydomain.com", blade_locate_response_handler, NULL);
|
||||
}
|
||||
|
||||
//ks_bool_t on_blade_chat_send_response(blade_response_t *bres);
|
||||
//
|
||||
//ks_bool_t on_blade_chat_join_response(blade_response_t *bres) // @todo this should get userdata passed in from when the callback is registered
|
||||
//{
|
||||
// blade_session_t *bs = NULL;
|
||||
// cJSON *req = NULL;
|
||||
// cJSON *params = NULL;
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Received Chat Join Response!\n");
|
||||
//
|
||||
// bs = blade_handle_sessions_get(bres->handle, bres->session_id);
|
||||
// if (!bs) {
|
||||
// ks_log(KS_LOG_DEBUG, "Unknown Session: %s\n", bres->session_id);
|
||||
// return KS_FALSE;
|
||||
// }
|
||||
//
|
||||
// blade_jsonrpc_request_raw_create(blade_handle_pool_get(bres->handle), &req, ¶ms, NULL, "blade.chat.send");
|
||||
// ks_assert(req);
|
||||
// ks_assert(params);
|
||||
//
|
||||
// cJSON_AddStringToObject(params, "message", "Hello World!");
|
||||
//
|
||||
// blade_session_send(bs, req, on_blade_chat_send_response);
|
||||
//
|
||||
// blade_session_read_unlock(bs);
|
||||
//
|
||||
// return KS_FALSE;
|
||||
//}
|
||||
//
|
||||
//ks_bool_t on_blade_chat_send_response(blade_response_t *bres) // @todo this should get userdata passed in from when the callback is registered
|
||||
//{
|
||||
// ks_log(KS_LOG_DEBUG, "Received Chat Send Response!\n");
|
||||
// return KS_FALSE;
|
||||
//}
|
||||
//
|
||||
//void command_chat(blade_handle_t *bh, char *args)
|
||||
//{
|
||||
// char *cmd = NULL;
|
||||
//
|
||||
// ks_assert(bh);
|
||||
// ks_assert(args);
|
||||
//
|
||||
// parse_argument(&args, &cmd, ' ');
|
||||
// ks_log(KS_LOG_DEBUG, "Chat Command: %s, Args: %s\n", cmd, args);
|
||||
//
|
||||
// if (!strcmp(cmd, "leave")) {
|
||||
// } else if (!strcmp(cmd, "send")) {
|
||||
// char *sid = NULL;
|
||||
// blade_session_t *bs = NULL;
|
||||
// cJSON *req = NULL;
|
||||
// cJSON *params = NULL;
|
||||
//
|
||||
// parse_argument(&args, &sid, ' ');
|
||||
//
|
||||
// bs = blade_handle_sessions_get(bh, sid);
|
||||
// if (!bs) {
|
||||
// ks_log(KS_LOG_DEBUG, "Unknown Session: %s\n", sid);
|
||||
// return;
|
||||
// }
|
||||
// blade_jsonrpc_request_raw_create(blade_handle_pool_get(bh), &req, ¶ms, NULL, "blade.chat.send");
|
||||
// ks_assert(req);
|
||||
// ks_assert(params);
|
||||
//
|
||||
// cJSON_AddStringToObject(params, "message", args);
|
||||
//
|
||||
// blade_session_send(bs, req, on_blade_chat_send_response);
|
||||
//
|
||||
// blade_session_read_unlock(bs);
|
||||
//
|
||||
// cJSON_Delete(req);
|
||||
// } else {
|
||||
// ks_log(KS_LOG_DEBUG, "Unknown Chat Command: %s\n", cmd);
|
||||
// }
|
||||
//}
|
||||
/* 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:
|
||||
*/
|
||||
|
|
|
@ -16,45 +16,70 @@ struct command_def_s {
|
|||
};
|
||||
|
||||
void command_quit(blade_handle_t *bh, char *args);
|
||||
void command_locate(blade_handle_t *bh, char *args);
|
||||
|
||||
static const struct command_def_s command_defs[] = {
|
||||
{ "quit", command_quit },
|
||||
{ "locate", command_locate },
|
||||
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
|
||||
|
||||
//ks_status_t blade_module_chat_create(blade_module_t **bmP, blade_handle_t *bh);
|
||||
//ks_status_t blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config);
|
||||
//ks_status_t blade_module_chat_on_shutdown(blade_module_t *bm);
|
||||
//
|
||||
//typedef struct blade_module_chat_s blade_module_chat_t;
|
||||
//struct blade_module_chat_s {
|
||||
// blade_handle_t *handle;
|
||||
// ks_pool_t *pool;
|
||||
// ks_thread_pool_t *tpool;
|
||||
// blade_module_t *module;
|
||||
// //blade_module_callbacks_t *module_callbacks;
|
||||
//
|
||||
// blade_space_t *blade_chat_space;
|
||||
// const char *session_state_callback_id;
|
||||
// ks_list_t *participants;
|
||||
//};
|
||||
//
|
||||
//void blade_module_chat_on_session_state(blade_session_t *bs, blade_session_state_condition_t condition, void *data);
|
||||
//
|
||||
//ks_bool_t blade_chat_join_request_handler(blade_module_t *bm, blade_request_t *breq);
|
||||
//ks_bool_t blade_chat_leave_request_handler(blade_module_t *bm, blade_request_t *breq);
|
||||
//ks_bool_t blade_chat_send_request_handler(blade_module_t *bm, blade_request_t *breq);
|
||||
//
|
||||
//static blade_module_callbacks_t g_module_chat_callbacks =
|
||||
//{
|
||||
// blade_module_chat_on_startup,
|
||||
// blade_module_chat_on_shutdown,
|
||||
//};
|
||||
ks_bool_t blade_publish_response_handler(blade_rpc_response_t *brpcres, void *data)
|
||||
{
|
||||
blade_handle_t *bh = NULL;
|
||||
blade_session_t *bs = NULL;
|
||||
|
||||
ks_assert(brpcres);
|
||||
|
||||
bh = blade_rpc_response_handle_get(brpcres);
|
||||
ks_assert(bh);
|
||||
|
||||
bs = blade_handle_sessions_lookup(bh, blade_rpc_response_sessionid_get(brpcres));
|
||||
ks_assert(bs);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) blade.publish response processing\n", blade_session_id_get(bs));
|
||||
|
||||
blade_session_read_unlock(bs);
|
||||
|
||||
return KS_FALSE;
|
||||
}
|
||||
|
||||
ks_bool_t test_echo_request_handler(blade_rpc_request_t *brpcreq, void *data)
|
||||
{
|
||||
blade_handle_t *bh = NULL;
|
||||
blade_session_t *bs = NULL;
|
||||
cJSON *params = NULL;
|
||||
cJSON *result = NULL;
|
||||
const char *text = NULL;
|
||||
|
||||
ks_assert(brpcreq);
|
||||
|
||||
bh = blade_rpc_request_handle_get(brpcreq);
|
||||
ks_assert(bh);
|
||||
|
||||
bs = blade_handle_sessions_lookup(bh, blade_rpc_response_sessionid_get(brpcreq));
|
||||
ks_assert(bs);
|
||||
|
||||
// @todo get the inner parameters of a blade.execute request for protocolrpcs
|
||||
params = blade_protocol_execute_request_params_get(brpcreq);
|
||||
ks_assert(params);
|
||||
|
||||
text = cJSON_GetObjectCstr(params, "text");
|
||||
ks_assert(text);
|
||||
|
||||
ks_log(KS_LOG_DEBUG, "Session (%s) test.echo request processing\n", blade_session_id_get(bs));
|
||||
|
||||
blade_session_read_unlock(bs);
|
||||
|
||||
// @todo build and send response
|
||||
result = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(result, "text", text);
|
||||
|
||||
blade_protocol_execute_response_send(brpcreq, result);
|
||||
|
||||
return KS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
|
@ -62,8 +87,6 @@ int main(int argc, char **argv)
|
|||
blade_handle_t *bh = NULL;
|
||||
config_t config;
|
||||
config_setting_t *config_blade = NULL;
|
||||
//blade_module_t *mod_chat = NULL;
|
||||
//blade_identity_t *id = NULL;
|
||||
const char *cfgpath = "blades.cfg";
|
||||
const char *autoconnect = NULL;
|
||||
|
||||
|
@ -73,7 +96,6 @@ int main(int argc, char **argv)
|
|||
|
||||
blade_handle_create(&bh);
|
||||
|
||||
//if (argc > 1) cfgpath = argv[1];
|
||||
if (argc > 1) autoconnect = argv[1];
|
||||
|
||||
config_init(&config);
|
||||
|
@ -93,10 +115,6 @@ int main(int argc, char **argv)
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// must occur before startup
|
||||
//blade_module_chat_create(&mod_chat, bh);
|
||||
//blade_handle_module_register(mod_chat);
|
||||
|
||||
if (blade_handle_startup(bh, config_blade) != KS_STATUS_SUCCESS) {
|
||||
ks_log(KS_LOG_ERROR, "Blade startup failed\n");
|
||||
return EXIT_FAILURE;
|
||||
|
@ -105,6 +123,7 @@ int main(int argc, char **argv)
|
|||
if (autoconnect) {
|
||||
blade_connection_t *bc = NULL;
|
||||
blade_identity_t *target = NULL;
|
||||
blade_rpc_t *brpc = NULL;
|
||||
|
||||
blade_identity_create(&target, blade_handle_pool_get(bh));
|
||||
|
||||
|
@ -112,9 +131,13 @@ int main(int argc, char **argv)
|
|||
|
||||
blade_identity_destroy(&target);
|
||||
|
||||
ks_sleep_ms(5000); // @todo use session state change callback to know when the session is ready, this ensures it's ready before trying to publish upstream
|
||||
ks_sleep_ms(5000); // @todo use session state change callback to know when the session is ready, this hack temporarily ensures it's ready before trying to publish upstream
|
||||
|
||||
blade_protocol_publish(bh, "test", "mydomain.com");
|
||||
blade_rpc_create(&brpc, bh, "test.echo", "test", "mydomain.com", test_echo_request_handler, NULL);
|
||||
blade_handle_protocolrpc_register(brpc);
|
||||
|
||||
// @todo build up json-based method schema for each protocolrpc registered above, and pass into blade_protocol_publish() to attach to the request, to be stored in the blade_protocol_t tracked by the master node
|
||||
blade_protocol_publish(bh, "test", "mydomain.com", blade_publish_response_handler, NULL);
|
||||
}
|
||||
|
||||
loop(bh);
|
||||
|
@ -193,339 +216,6 @@ void command_quit(blade_handle_t *bh, char *args)
|
|||
g_shutdown = KS_TRUE;
|
||||
}
|
||||
|
||||
void command_locate(blade_handle_t *bh, char *args)
|
||||
{
|
||||
ks_assert(bh);
|
||||
ks_assert(args);
|
||||
|
||||
blade_protocol_locate(bh, "test", "mydomain.com");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//static void blade_module_chat_cleanup(ks_pool_t *pool, void *ptr, void *arg, ks_pool_cleanup_action_t action, ks_pool_cleanup_type_t type)
|
||||
//{
|
||||
// blade_module_chat_t *bm_chat = (blade_module_chat_t *)ptr;
|
||||
//
|
||||
// ks_assert(bm_chat);
|
||||
//
|
||||
// switch (action) {
|
||||
// case KS_MPCL_ANNOUNCE:
|
||||
// break;
|
||||
// case KS_MPCL_TEARDOWN:
|
||||
// break;
|
||||
// case KS_MPCL_DESTROY:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//
|
||||
//ks_status_t blade_module_chat_create(blade_module_t **bmP, blade_handle_t *bh)
|
||||
//{
|
||||
// blade_module_chat_t *bm_chat = NULL;
|
||||
// ks_pool_t *pool = NULL;
|
||||
//
|
||||
// ks_assert(bmP);
|
||||
// ks_assert(bh);
|
||||
//
|
||||
// ks_pool_open(&pool);
|
||||
// ks_assert(pool);
|
||||
//
|
||||
// bm_chat = ks_pool_alloc(pool, sizeof(blade_module_chat_t));
|
||||
// bm_chat->handle = bh;
|
||||
// bm_chat->pool = pool;
|
||||
// bm_chat->tpool = blade_handle_tpool_get(bh);
|
||||
// bm_chat->session_state_callback_id = NULL;
|
||||
//
|
||||
// ks_list_create(&bm_chat->participants, pool);
|
||||
// ks_assert(bm_chat->participants);
|
||||
//
|
||||
// blade_module_create(&bm_chat->module, bh, pool, bm_chat, &g_module_chat_callbacks);
|
||||
// ks_assert(bm_chat->module);
|
||||
//
|
||||
// ks_pool_set_cleanup(pool, bm_chat, NULL, blade_module_chat_cleanup);
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Created\n");
|
||||
//
|
||||
// *bmP = bm_chat->module;
|
||||
//
|
||||
// return KS_STATUS_SUCCESS;
|
||||
//}
|
||||
//
|
||||
//
|
||||
//ks_status_t blade_module_chat_config(blade_module_chat_t *bm_chat, config_setting_t *config)
|
||||
//{
|
||||
// config_setting_t *chat = NULL;
|
||||
//
|
||||
// ks_assert(bm_chat);
|
||||
// ks_assert(config);
|
||||
//
|
||||
// if (!config_setting_is_group(config)) {
|
||||
// ks_log(KS_LOG_DEBUG, "!config_setting_is_group(config)\n");
|
||||
// return KS_STATUS_FAIL;
|
||||
// }
|
||||
//
|
||||
// chat = config_setting_get_member(config, "chat");
|
||||
// if (chat) {
|
||||
// }
|
||||
//
|
||||
//
|
||||
// // Configuration is valid, now assign it to the variables that are used
|
||||
// // If the configuration was invalid, then this does not get changed
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Configured\n");
|
||||
//
|
||||
// return KS_STATUS_SUCCESS;
|
||||
//}
|
||||
//
|
||||
//ks_status_t blade_module_chat_on_startup(blade_module_t *bm, config_setting_t *config)
|
||||
//{
|
||||
// blade_module_chat_t *bm_chat = NULL;
|
||||
// blade_space_t *space = NULL;
|
||||
// blade_method_t *method = NULL;
|
||||
//
|
||||
// ks_assert(bm);
|
||||
// ks_assert(config);
|
||||
//
|
||||
// bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||
//
|
||||
// if (blade_module_chat_config(bm_chat, config) != KS_STATUS_SUCCESS) {
|
||||
// ks_log(KS_LOG_DEBUG, "blade_module_chat_config failed\n");
|
||||
// return KS_STATUS_FAIL;
|
||||
// }
|
||||
//
|
||||
// blade_space_create(&space, bm_chat->handle, bm, "blade.chat");
|
||||
// ks_assert(space);
|
||||
//
|
||||
// bm_chat->blade_chat_space = space;
|
||||
//
|
||||
// blade_method_create(&method, space, "join", blade_chat_join_request_handler);
|
||||
// ks_assert(method);
|
||||
// blade_space_methods_add(space, method);
|
||||
//
|
||||
// blade_method_create(&method, space, "leave", blade_chat_leave_request_handler);
|
||||
// ks_assert(method);
|
||||
// blade_space_methods_add(space, method);
|
||||
//
|
||||
// blade_method_create(&method, space, "send", blade_chat_send_request_handler);
|
||||
// ks_assert(method);
|
||||
// blade_space_methods_add(space, method);
|
||||
//
|
||||
// blade_handle_space_register(space);
|
||||
//
|
||||
// blade_handle_session_state_callback_register(blade_module_handle_get(bm), bm, blade_module_chat_on_session_state, &bm_chat->session_state_callback_id);
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Started\n");
|
||||
//
|
||||
// return KS_STATUS_SUCCESS;
|
||||
//}
|
||||
//
|
||||
//ks_status_t blade_module_chat_on_shutdown(blade_module_t *bm)
|
||||
//{
|
||||
// blade_module_chat_t *bm_chat = NULL;
|
||||
//
|
||||
// ks_assert(bm);
|
||||
//
|
||||
// bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||
// ks_assert(bm_chat);
|
||||
//
|
||||
// if (bm_chat->session_state_callback_id) blade_handle_session_state_callback_unregister(blade_module_handle_get(bm), bm_chat->session_state_callback_id);
|
||||
// bm_chat->session_state_callback_id = NULL;
|
||||
//
|
||||
// if (bm_chat->blade_chat_space) blade_handle_space_unregister(bm_chat->blade_chat_space);
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Stopped\n");
|
||||
//
|
||||
// return KS_STATUS_SUCCESS;
|
||||
//}
|
||||
//
|
||||
//void blade_module_chat_on_session_state(blade_session_t *bs, blade_session_state_condition_t condition, void *data)
|
||||
//{
|
||||
// blade_module_t *bm = NULL;
|
||||
// blade_module_chat_t *bm_chat = NULL;
|
||||
//
|
||||
// ks_assert(bs);
|
||||
// ks_assert(data);
|
||||
//
|
||||
// bm = (blade_module_t *)data;
|
||||
// bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||
// ks_assert(bm_chat);
|
||||
//
|
||||
// if (blade_session_state_get(bs) == BLADE_SESSION_STATE_HANGUP && condition == BLADE_SESSION_STATE_CONDITION_PRE) {
|
||||
// cJSON *props = NULL;
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Removing session from chat participants if present\n");
|
||||
//
|
||||
// props = blade_session_properties_get(bs);
|
||||
// ks_assert(props);
|
||||
//
|
||||
// cJSON_DeleteItemFromObject(props, "blade.chat.participant");
|
||||
//
|
||||
// ks_list_delete(bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and search manually, also free the id
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//ks_bool_t blade_chat_join_request_handler(blade_module_t *bm, blade_request_t *breq)
|
||||
//{
|
||||
// blade_module_chat_t *bm_chat = NULL;
|
||||
// blade_session_t *bs = NULL;
|
||||
// cJSON *res = NULL;
|
||||
// cJSON *props = NULL;
|
||||
// cJSON *props_participant = NULL;
|
||||
//
|
||||
// ks_assert(bm);
|
||||
// ks_assert(breq);
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Request Received!\n");
|
||||
//
|
||||
// bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||
// ks_assert(bm_chat);
|
||||
//
|
||||
// bs = blade_handle_sessions_get(breq->handle, breq->session_id);
|
||||
// ks_assert(bs);
|
||||
//
|
||||
// // @todo properties only used to demonstrate a flexible container for session data, should just rely on the participants list/hash
|
||||
// blade_session_properties_write_lock(bs, KS_TRUE);
|
||||
//
|
||||
// props = blade_session_properties_get(bs);
|
||||
// ks_assert(props);
|
||||
//
|
||||
// props_participant = cJSON_GetObjectItem(props, "blade.chat.participant");
|
||||
// if (props_participant && props_participant->type == cJSON_True) {
|
||||
// ks_log(KS_LOG_DEBUG, "Session (%s) attempted to join chat but is already a participant\n", blade_session_id_get(bs));
|
||||
// blade_rpc_error_create(&res, NULL, breq->message_id, -10000, "Already a participant of chat");
|
||||
// }
|
||||
// else {
|
||||
// ks_log(KS_LOG_DEBUG, "Session (%s) joined chat\n", blade_session_id_get(bs));
|
||||
//
|
||||
// if (props_participant) props_participant->type = cJSON_True;
|
||||
// else cJSON_AddTrueToObject(props, "blade.chat.participant");
|
||||
//
|
||||
// ks_list_append(bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and cleanup when removed
|
||||
//
|
||||
// blade_rpc_response_create(&res, NULL, breq->message_id);
|
||||
//
|
||||
// // @todo create an event to send to participants when a session joins and leaves, send after main response though
|
||||
// }
|
||||
//
|
||||
// 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_chat_leave_request_handler(blade_module_t *bm, blade_request_t *breq)
|
||||
//{
|
||||
// blade_module_chat_t *bm_chat = NULL;
|
||||
// blade_session_t *bs = NULL;
|
||||
// cJSON *res = NULL;
|
||||
// cJSON *props = NULL;
|
||||
// cJSON *props_participant = NULL;
|
||||
//
|
||||
// ks_assert(bm);
|
||||
// ks_assert(breq);
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Request Received!\n");
|
||||
//
|
||||
// bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||
// ks_assert(bm_chat);
|
||||
//
|
||||
// bs = blade_handle_sessions_get(breq->handle, breq->session_id);
|
||||
// ks_assert(bs);
|
||||
//
|
||||
// blade_session_properties_write_lock(bs, KS_TRUE);
|
||||
//
|
||||
// props = blade_session_properties_get(bs);
|
||||
// ks_assert(props);
|
||||
//
|
||||
// props_participant = cJSON_GetObjectItem(props, "blade.chat.participant");
|
||||
// if (!props_participant || props_participant->type == cJSON_False) {
|
||||
// ks_log(KS_LOG_DEBUG, "Session (%s) attempted to leave chat but is not a participant\n", blade_session_id_get(bs));
|
||||
// blade_rpc_error_create(&res, NULL, breq->message_id, -10000, "Not a participant of chat");
|
||||
// }
|
||||
// else {
|
||||
// ks_log(KS_LOG_DEBUG, "Session (%s) left chat\n", blade_session_id_get(bs));
|
||||
//
|
||||
// cJSON_DeleteItemFromObject(props, "blade.chat.participant");
|
||||
//
|
||||
// ks_list_delete(bm_chat->participants, blade_session_id_get(bs)); // @todo make copy of session id instead and search manually, also free the id
|
||||
//
|
||||
// blade_rpc_response_create(&res, NULL, breq->message_id);
|
||||
//
|
||||
// // @todo create an event to send to participants when a session joins and leaves, send after main response though
|
||||
// }
|
||||
//
|
||||
// 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_chat_send_request_handler(blade_module_t *bm, blade_request_t *breq)
|
||||
//{
|
||||
// blade_module_chat_t *bm_chat = NULL;
|
||||
// blade_session_t *bs = NULL;
|
||||
// cJSON *params = NULL;
|
||||
// cJSON *res = NULL;
|
||||
// cJSON *event = NULL;
|
||||
// const char *message = NULL;
|
||||
// ks_bool_t sendevent = KS_FALSE;
|
||||
//
|
||||
// ks_assert(bm);
|
||||
// ks_assert(breq);
|
||||
//
|
||||
// ks_log(KS_LOG_DEBUG, "Request Received!\n");
|
||||
//
|
||||
// bm_chat = (blade_module_chat_t *)blade_module_data_get(bm);
|
||||
// ks_assert(bm_chat);
|
||||
//
|
||||
// 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 send chat message 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 (!(message = cJSON_GetObjectCstr(params, "message"))) {
|
||||
// ks_log(KS_LOG_DEBUG, "Session (%s) attempted to send chat message with no 'message'\n", blade_session_id_get(bs));
|
||||
// blade_rpc_error_create(&res, NULL, breq->message_id, -32602, "Missing params message string");
|
||||
// }
|
||||
//
|
||||
// bs = blade_handle_sessions_get(breq->handle, breq->session_id);
|
||||
// ks_assert(bs);
|
||||
//
|
||||
// if (!res) {
|
||||
// blade_rpc_response_create(&res, NULL, breq->message_id);
|
||||
// sendevent = KS_TRUE;
|
||||
// }
|
||||
// blade_session_send(bs, res, NULL);
|
||||
//
|
||||
// blade_session_read_unlock(bs);
|
||||
//
|
||||
// cJSON_Delete(res);
|
||||
//
|
||||
// if (sendevent) {
|
||||
// blade_rpc_event_create(&event, &res, "blade.chat.message");
|
||||
// ks_assert(event);
|
||||
// cJSON_AddStringToObject(res, "from", breq->session_id); // @todo should really be the identity, but we don't have that in place yet
|
||||
// cJSON_AddStringToObject(res, "message", message);
|
||||
//
|
||||
// blade_handle_sessions_send(breq->handle, bm_chat->participants, NULL, event);
|
||||
//
|
||||
// cJSON_Delete(event);
|
||||
// }
|
||||
//
|
||||
// return KS_FALSE;
|
||||
//}
|
||||
|
||||
|
||||
/* For Emacs:
|
||||
* Local Variables:
|
||||
|
|
Loading…
Reference in New Issue