diff options
Diffstat (limited to 'src/ClientManager.cpp')
-rwxr-xr-x | src/ClientManager.cpp | 433 |
1 files changed, 218 insertions, 215 deletions
diff --git a/src/ClientManager.cpp b/src/ClientManager.cpp index 74d672d..cbda0e2 100755 --- a/src/ClientManager.cpp +++ b/src/ClientManager.cpp @@ -1,215 +1,218 @@ -/*
- * Copyright (C) 2020 MERA
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "ClientManager.h"
-#include "hmi-debug.h"
-
-#include <set>
-#include <json-c/json.h>
-
-// static
-void ClientManager::cbRemoveClientCtx(void *data)
-{
- ClientManager::instance().removeClient((ClientManager::ClientCtx*)data);
-}
-
-
-// static
-ClientManager& ClientManager::instance()
-{
- static ClientManager instance;
- return instance;
-}
-
-
-ClientManager::~ClientManager()
-{
- std::lock_guard<std::mutex> lock(this->m_mutex);
- for (auto cl : m_clients)
- delete cl.second;
-}
-
-
-ClientManager::ClientCtx* ClientManager::addClient(afb_req_t req, const std::string& appid)
-{
- ClientCtx* ctx = (ClientCtx*)afb_req_context_get(req);
- if (!ctx)
- {
- HMI_NOTICE("cloudproxy-service", "create new session for %s", appid.c_str());
- ctx = new ClientCtx{appid, afb_api_make_event(req->api, appid.c_str())};
- afb_req_session_set_LOA(req, 1);
- afb_req_context_set(req, ctx, cbRemoveClientCtx);
- }
-
- m_clients[appid] = ctx;
- return ctx;
-}
-
-
-void ClientManager::removeClient(ClientCtx* ctx)
-{
- if(!ctx)
- {
- HMI_ERROR("cloudproxy-service", "data is nullptr");
- return;
- }
-
- HMI_NOTICE("cloudproxy-service", "remove app %s", ctx->appid.c_str());
- std::lock_guard<std::mutex> lock(this->m_mutex);
-
- auto it = m_clients.find(ctx->appid);
- if (it != m_clients.end())
- {
- delete it->second;
- m_clients.erase(it);
- }
-}
-
-
-bool ClientManager::handleRequest(afb_req_t request, const std::string& verb, const std::string& appid)
-{
- HMI_NOTICE("cloudproxy-service", "handleRequest: verb='%s', appid='%s'", verb.c_str(), appid.c_str());
- std::lock_guard<std::mutex> lock(this->m_mutex);
-
- if (appid.empty())
- {
- HMI_ERROR("cloudproxy-service", "appid is empty");
- return false;
- }
-
- auto client_it = m_clients.find(appid);
- if (verb != "subscribe" && client_it == m_clients.end())
- {
- HMI_NOTICE("cloudproxy-service", "client with appid '%s' is not registered", appid.c_str());
- return false;
- }
-
- if (verb == "subscribe")
- {
- const char *value = afb_req_value(request, "event");
- if(!value)
- {
- HMI_ERROR("cloudproxy-service", "Can't subscribe: event name is not defined");
- return false;
- }
- std::string req_event{value};
- HMI_NOTICE("cloudproxy-service", "subscribe req: appid '%s', event '%s'", appid.c_str(), req_event.c_str());
-
- if (!isSupportedEvent(req_event))
- {
- HMI_ERROR("cloudproxy-service", "event '%s' is not supported", req_event.c_str());
- return false;
- }
-
- ClientCtx* ctx = addClient(request, appid);
- ctx->subs_events.insert(req_event);
- if(!ctx->subscription)
- {
- if(afb_req_subscribe(request, ctx->event) == 0)
- {
- ctx->subscription = true;
- }
- else
- {
- HMI_ERROR("cloudproxy-service", "API error in afb_req_subscribe");
- return false;
- }
- }
-
- return true;
- }
- else if (verb == "unsubscribe")
- {
- const char *value = afb_req_value(request, "event");
- if(!value)
- {
- HMI_ERROR("cloudproxy-service", "Can't unsubscribe: event name is not defined");
- return false;
- }
- std::string req_event{value};
- HMI_NOTICE("cloudproxy-service", "unsubscribe req: appid '%s', event '%s'", appid.c_str(), req_event.c_str());
-
- ClientCtx* ctx{client_it->second};
- ctx->subs_events.erase(req_event);
-
- if(ctx->subs_events.empty())
- {
- if (afb_req_unsubscribe(request, ctx->event) != 0)
- HMI_ERROR("cloudproxy-service", "API error in afb_req_unsubscribe");
-
- ctx->subscription = false;
- }
-
- return true;
- }
-
- HMI_NOTICE("cloudproxy-service", "Unsupported verb '%s'", verb.c_str());
- return false;
-}
-
-
-bool ClientManager::isSupportedEvent(const std::string& event)
-{
- const std::set<std::string> event_list{
- "sendMessageConfirmation",
- "receivedMessage"
- };
-
- return (event_list.end() != event_list.find(event));
-}
-
-
-bool ClientManager::emitReceivedMessage(const std::string& appid, const std::string& data)
-{
- std::lock_guard<std::mutex> lock(this->m_mutex);
-
- auto it = m_clients.find(appid);
- if (it == m_clients.end())
- {
- HMI_WARNING("cloudproxy-service", "Client with appid '%s' is not present in list", appid.c_str());
- // print app list
- for (const auto& i : m_clients)
- HMI_DEBUG("cloudproxy-service", "Client list: appid '%s' - '%s'", i.first.c_str(), i.second->appid.c_str());
-
- return false;
- }
-
- json_object* push_obj = json_object_new_object();
- json_object_object_add(push_obj, "type", json_object_new_string("receivedMessage"));
- json_object_object_add(push_obj, "data", json_object_new_string(data.c_str()));
- return (0 == afb_event_push(it->second->event, push_obj));
-}
-
-bool ClientManager::emitSendMessageConfirmation(const std::string& appid, bool result)
-{
- std::lock_guard<std::mutex> lock(this->m_mutex);
-
- auto it = m_clients.find(appid);
- if (it == m_clients.end())
- {
- HMI_WARNING("cloudproxy-service", "Client with appid '%s' is not present in list", appid.c_str());
- // print app list
- for (const auto& i : m_clients)
- HMI_DEBUG("cloudproxy-service", "Client list: appid '%s' - '%s'", i.first.c_str(), i.second->appid.c_str());
-
- return false;
- }
-
- json_object* push_obj = json_object_new_object();
- json_object_object_add(push_obj, "type", json_object_new_string("sendMessageConfirmation"));
- json_object_object_add(push_obj, "result", json_object_new_boolean(result));
- return (0 == afb_event_push(it->second->event, push_obj));
-}
+/* + * Copyright (C) 2020 MERA + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ClientManager.h" +#include "CloudType.h" + +#include <set> +#include <json-c/json.h> +#include <afb/afb-binding.h> // for AFB_* logger + +// static +void ClientManager::cbRemoveClientCtx(void *data) +{ + ClientManager::instance().removeClient((ClientManager::ClientCtx*)data); +} + + +// static +ClientManager& ClientManager::instance() +{ + static ClientManager instance; + return instance; +} + + +ClientManager::~ClientManager() +{ + std::lock_guard<std::mutex> lock(this->m_mutex); + for (auto cl : m_clients) + delete cl.second; +} + + +ClientManager::ClientCtx* ClientManager::addClient(afb_req_t req, const std::string& appid) +{ + ClientCtx* ctx = (ClientCtx*)afb_req_context_get(req); + if (!ctx) + { + AFB_NOTICE("create new session for %s", appid.c_str()); + ctx = new ClientCtx{appid, afb_api_make_event(req->api, appid.c_str())}; + afb_req_session_set_LOA(req, 1); + afb_req_context_set(req, ctx, cbRemoveClientCtx); + } + + m_clients[appid] = ctx; + return ctx; +} + + +void ClientManager::removeClient(ClientCtx* ctx) +{ + if(!ctx) + { + AFB_ERROR("data is nullptr"); + return; + } + + AFB_NOTICE("remove app %s", ctx->appid.c_str()); + std::lock_guard<std::mutex> lock(this->m_mutex); + + auto it = m_clients.find(ctx->appid); + if (it != m_clients.end()) + { + delete it->second; + m_clients.erase(it); + } +} + + +bool ClientManager::handleRequest(afb_req_t request, const std::string& verb, const std::string& appid) +{ + AFB_NOTICE("handleRequest: verb='%s', appid='%s'", verb.c_str(), appid.c_str()); + std::lock_guard<std::mutex> lock(this->m_mutex); + + if (appid.empty()) + { + AFB_ERROR("appid is empty"); + return false; + } + + auto client_it = m_clients.find(appid); + if (verb != "subscribe" && client_it == m_clients.end()) + { + AFB_NOTICE("client with appid '%s' is not registered", appid.c_str()); + return false; + } + + if (verb == "subscribe") + { + const char *value = afb_req_value(request, "event"); + if(!value) + { + AFB_ERROR("Can't subscribe: event name is not defined"); + return false; + } + std::string req_event{value}; + AFB_NOTICE("subscribe req: appid '%s', event '%s'", appid.c_str(), req_event.c_str()); + + if (!isSupportedEvent(req_event)) + { + AFB_ERROR("event '%s' is not supported", req_event.c_str()); + return false; + } + + ClientCtx* ctx = addClient(request, appid); + ctx->subs_events.insert(req_event); + if(!ctx->subscription) + { + if(afb_req_subscribe(request, ctx->event) == 0) + { + ctx->subscription = true; + } + else + { + AFB_ERROR("API error in afb_req_subscribe"); + return false; + } + } + + return true; + } + else if (verb == "unsubscribe") + { + const char *value = afb_req_value(request, "event"); + if(!value) + { + AFB_ERROR("Can't unsubscribe: event name is not defined"); + return false; + } + std::string req_event{value}; + AFB_NOTICE("unsubscribe req: appid '%s', event '%s'", appid.c_str(), req_event.c_str()); + + ClientCtx* ctx{client_it->second}; + ctx->subs_events.erase(req_event); + + if(ctx->subs_events.empty()) + { + if (afb_req_unsubscribe(request, ctx->event) != 0) + AFB_ERROR("API error in afb_req_unsubscribe"); + + ctx->subscription = false; + } + + return true; + } + + AFB_NOTICE("Unsupported verb '%s'", verb.c_str()); + return false; +} + + +bool ClientManager::isSupportedEvent(const std::string& event) +{ + const std::set<std::string> event_list{ + "sendMessageConfirmation", + "receivedMessage" + }; + + return (event_list.end() != event_list.find(event)); +} + + +bool ClientManager::emitReceivedMessage(const std::string& appid, const std::string& cloud_type, const std::string& data) +{ + std::lock_guard<std::mutex> lock(this->m_mutex); + + auto it = m_clients.find(appid); + if (it == m_clients.end()) + { + AFB_WARNING("Client with appid '%s' is not present in list", appid.c_str()); + // print app list + for (const auto& i : m_clients) + AFB_DEBUG("Client list: appid '%s' - '%s'", i.first.c_str(), i.second->appid.c_str()); + + return false; + } + + json_object* push_obj = json_object_new_object(); + json_object_object_add(push_obj, "type", json_object_new_string("receivedMessage")); + json_object_object_add(push_obj, "cloud_type", json_object_new_string(cloud_type.c_str())); + json_object_object_add(push_obj, "data", json_object_new_string(data.c_str())); + return (0 == afb_event_push(it->second->event, push_obj)); +} + +bool ClientManager::emitSendMessageConfirmation(const std::string& appid, const std::string& cloud_type, bool result) +{ + std::lock_guard<std::mutex> lock(this->m_mutex); + + auto it = m_clients.find(appid); + if (it == m_clients.end()) + { + AFB_WARNING("Client with appid '%s' is not present in list", appid.c_str()); + // print app list + for (const auto& i : m_clients) + AFB_DEBUG("Client list: appid '%s' - '%s'", i.first.c_str(), i.second->appid.c_str()); + + return false; + } + + json_object* push_obj = json_object_new_object(); + json_object_object_add(push_obj, "type", json_object_new_string("sendMessageConfirmation")); + json_object_object_add(push_obj, "cloud_type", json_object_new_string(cloud_type.c_str())); + json_object_object_add(push_obj, "result", json_object_new_boolean(result)); + return (0 == afb_event_push(it->second->event, push_obj)); +} |