Add connection check 62/27262/28
authorMarcin Niesluchowski <m.niesluchow@samsung.com>
Mon, 15 Sep 2014 09:54:48 +0000 (11:54 +0200)
committerMarcin Niesluchowski <m.niesluchow@samsung.com>
Mon, 13 Oct 2014 17:13:39 +0000 (19:13 +0200)
cynara_async_check_cache should return CYNARA_API_CACHE_MISS if
disconnected.
cynara_async_create_request and cynara_async_cancel_request should try
reconnecting if disconnected and return CYNARA_API_SERVICE_NOT_AVAILABLE
on failure.
As cynara_async is connecting asynchronously, it could take connection
in progress state which is resolved in cynara_async_process and treated
as connected in other functions. As this state exists after reconnecting,
there should be no cache entries. cynara_async_process should complete
connecting if needed by waiting for write event. If connection fails in
cynara_async_process, then CYNARA_API_SERVICE_NOT_AVAILABLE should be
returned.

Change-Id: I2920f4dbd0bde3e7be74096db33f4ff465bc5028

src/client-async/CMakeLists.txt
src/client-async/callback/StatusCallback.cpp [new file with mode: 0644]
src/client-async/callback/StatusCallback.h [new file with mode: 0644]
src/client-async/logic/Logic.cpp
src/client-async/logic/Logic.h

index 1326f8d..5b3d404 100644 (file)
@@ -30,6 +30,7 @@ INCLUDE_DIRECTORIES(
 
 SET(LIB_CYNARA_ASYNC_SOURCES
     ${CYNARA_LIB_CYNARA_ASYNC_PATH}/api/client-async-api.cpp
+    ${CYNARA_LIB_CYNARA_ASYNC_PATH}/callback/StatusCallback.cpp
     ${CYNARA_LIB_CYNARA_ASYNC_PATH}/logic/Logic.cpp
     ${CYNARA_LIB_CYNARA_ASYNC_PATH}/sockets/SocketClientAsync.cpp
     )
@@ -44,7 +45,7 @@ SET_TARGET_PROPERTIES(
     )
 
 TARGET_LINK_LIBRARIES(${TARGET_LIB_CYNARA_ASYNC}
-    ${TARGET_CYNARA_COMMON}
+    ${TARGET_LIB_CYNARA_COMMON}
     )
 
 INSTALL(TARGETS ${TARGET_LIB_CYNARA_ASYNC} DESTINATION ${LIB_INSTALL_DIR})
diff --git a/src/client-async/callback/StatusCallback.cpp b/src/client-async/callback/StatusCallback.cpp
new file mode 100644 (file)
index 0000000..45da823
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/**
+ * @file        src/client-async/callback/StatusCallback.cpp
+ * @author      Marcin Niesluchowski <m.niesluchow@samsung.com>
+ * @version     1.0
+ * @brief       This file contains definition of StatusCallback class
+ */
+
+#include "StatusCallback.h"
+
+namespace Cynara {
+
+StatusCallback::StatusCallback(cynara_status_callback callback, void *userData)
+    : m_callback(callback), m_userData(userData), m_sockFd(-1),
+      m_status(cynara_async_status::CYNARA_STATUS_FOR_READ) {
+}
+
+void StatusCallback::onStatusChange(int newFd, cynara_async_status status) {
+    if (!m_callback)
+        return;
+    if (m_status == status && m_sockFd == newFd)
+        return;
+    m_callback(m_sockFd, newFd, status, m_userData);
+    m_sockFd = newFd;
+    m_status = status;
+}
+
+void StatusCallback::onDisconnected(void) {
+    onStatusChange(-1, cynara_async_status::CYNARA_STATUS_FOR_READ);
+}
+
+} // namespace Cynara
diff --git a/src/client-async/callback/StatusCallback.h b/src/client-async/callback/StatusCallback.h
new file mode 100644 (file)
index 0000000..468f0a0
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  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
+ */
+/**
+ * @file        src/client-async/callback/StatusCallback.h
+ * @author      Marcin Niesluchowski <m.niesluchow@samsung.com>
+ * @version     1.0
+ * @brief       This file contains declaration of StatusCallback class
+ */
+
+#ifndef SRC_CLIENT_ASYNC_CALLBACK_STATUSCALLBACK_H_
+#define SRC_CLIENT_ASYNC_CALLBACK_STATUSCALLBACK_H_
+
+#include <cynara-client-async.h>
+
+namespace Cynara {
+
+class StatusCallback {
+public:
+    StatusCallback(cynara_status_callback callback, void *userData);
+    ~StatusCallback() {};
+
+    void onStatusChange(int newFd, cynara_async_status status);
+    void onDisconnected(void);
+
+private:
+    cynara_status_callback m_callback;
+    void *m_userData;
+    int m_sockFd;
+    cynara_async_status m_status;
+};
+
+} // namespace Cynara
+
+#endif /* SRC_CLIENT_ASYNC_CALLBACK_STATUSCALLBACK_H_ */
index f20a216..04ae0de 100644 (file)
  *              libcynara-client-async class
  */
 
+#include <memory>
+
 #include <common.h>
+#include <exceptions/Exception.h>
+#include <exceptions/UnexpectedErrorException.h>
+#include <log/log.h>
+#include <protocol/ProtocolClient.h>
+#include <sockets/Socket.h>
+#include <sockets/SocketPath.h>
 
 #include "Logic.h"
 
 namespace Cynara {
 
-Logic::Logic(cynara_status_callback callback UNUSED, void *userStatusData UNUSED) {
-    // MOCKUP
+Logic::Logic(cynara_status_callback callback, void *userStatusData)
+    : m_statusCallback(callback, userStatusData) {
+    m_socketClient = std::make_shared<SocketClientAsync>(
+        SocketPath::client, std::make_shared<ProtocolClient>());
+}
+
+Logic::~Logic() {
+    onDisconnected();
 }
 
 int Logic::checkCache(const std::string &client UNUSED, const std::string &session UNUSED,
                       const std::string &user UNUSED, const std::string &privilege UNUSED) {
+    if (!checkCacheValid())
+        return CYNARA_API_CACHE_MISS;
+
     // MOCKUP
-    return CYNARA_API_CACHE_MISS;
+    return CYNARA_API_SUCCESS;
 }
 
 int Logic::createRequest(const std::string &client UNUSED, const std::string &session UNUSED,
                          const std::string &user UNUSED, const std::string &privilege UNUSED,
                          cynara_check_id &checkId UNUSED, cynara_response_callback callback UNUSED,
                          void *userResponseData UNUSED) {
+    if (!ensureConnection())
+        return CYNARA_API_SERVICE_NOT_AVAILABLE;
+
     // MOCKUP
     return CYNARA_API_MAX_PENDING_REQUESTS;
 }
 
-
 int Logic::process(void) {
+    bool completed;
+    int ret = completeConnection(completed);
+    if (!completed)
+        return ret;
+
     // MOCKUP
     return CYNARA_API_SUCCESS;
 }
 
 int Logic::cancelRequest(cynara_check_id checkId UNUSED) {
+    if (!ensureConnection())
+        return CYNARA_API_SERVICE_NOT_AVAILABLE;
+
     // MOCKUP
     return CYNARA_API_SUCCESS;
 }
 
+bool Logic::checkCacheValid(void) {
+    return m_socketClient->isConnected();
+}
+
+void Logic::prepareRequestsToSend(void) {
+    // MOCKUP
+}
+
+cynara_async_status Logic::socketDataStatus(void) {
+    return m_socketClient->isDataToSend() ? cynara_async_status::CYNARA_STATUS_FOR_RW
+                                          : cynara_async_status::CYNARA_STATUS_FOR_READ;
+}
+
+bool Logic::ensureConnection(void) {
+    if (m_socketClient->isConnected())
+        return true;
+    onDisconnected();
+    switch (m_socketClient->connect()) {
+        case Socket::ConnectionStatus::CONNECTION_SUCCEEDED:
+            prepareRequestsToSend();
+            m_statusCallback.onStatusChange(m_socketClient->getSockFd(), socketDataStatus());
+            return true;
+        case Socket::ConnectionStatus::CONNECTION_IN_PROGRESS:
+            prepareRequestsToSend();
+            m_statusCallback.onStatusChange(m_socketClient->getSockFd(),
+                                            cynara_async_status::CYNARA_STATUS_FOR_RW);
+            return true;
+        default:
+            return false;
+    }
+}
+
+int Logic::completeConnection(bool &completed) {
+    switch (m_socketClient->completeConnection()) {
+        case Socket::ConnectionStatus::ALREADY_CONNECTED:
+            completed = true;
+            return CYNARA_API_SUCCESS;
+        case Socket::ConnectionStatus::CONNECTION_SUCCEEDED:
+            m_statusCallback.onStatusChange(m_socketClient->getSockFd(), socketDataStatus());
+            completed = true;
+            return CYNARA_API_SUCCESS;
+        case Socket::ConnectionStatus::CONNECTION_IN_PROGRESS:
+            completed = false;
+            return CYNARA_API_SUCCESS;
+        default:
+            completed = false;
+            onDisconnected();
+            return CYNARA_API_SERVICE_NOT_AVAILABLE;
+    }
+}
+
+void Logic::onDisconnected(void) {
+    m_statusCallback.onDisconnected();
+}
+
 } // namespace Cynara
index d245501..bc43ad9 100644 (file)
 #define SRC_CLIENT_ASYNC_LOGIC_LOGIC_H_
 
 #include <api/ApiInterface.h>
+#include <callback/StatusCallback.h>
 #include <cynara-client-async.h>
+#include <sockets/SocketClientAsync.h>
 
 namespace Cynara {
 
 class Logic : public ApiInterface {
 public:
     Logic(cynara_status_callback callback, void *userStatusData);
-    virtual ~Logic() {};
+    virtual ~Logic();
 
     virtual int checkCache(const std::string &client, const std::string &session,
                            const std::string &user, const std::string &privilege);
@@ -42,6 +44,17 @@ public:
                               void *userResponseData);
     virtual int process(void);
     virtual int cancelRequest(cynara_check_id checkId);
+
+private:
+    StatusCallback m_statusCallback;
+    SocketClientAsyncPtr m_socketClient;
+
+    bool checkCacheValid(void);
+    void prepareRequestsToSend(void);
+    cynara_async_status socketDataStatus(void);
+    bool ensureConnection(void);
+    int completeConnection(bool &completed);
+    void onDisconnected(void);
 };
 
 } // namespace Cynara