From: Sangwan Kwon Date: Tue, 31 Dec 2019 07:13:54 +0000 (+0900) Subject: Reorganize rmi direcorty X-Git-Tag: submit/tizen/20200810.073515~119 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0eeb7bb32fab3a4294bd3bb2e9c3eafce0807ab3;p=platform%2Fcore%2Fsecurity%2Fvist.git Reorganize rmi direcorty - vist/rmi: API header to be exposed - vist/rmi/impl: Implementation to be hidden Signed-off-by: Sangwan Kwon --- diff --git a/src/vist/CMakeLists.txt b/src/vist/CMakeLists.txt index bf217bd..4114423 100644 --- a/src/vist/CMakeLists.txt +++ b/src/vist/CMakeLists.txt @@ -45,7 +45,6 @@ ADD_SUBDIRECTORY(klass) ADD_SUBDIRECTORY(logger) ADD_SUBDIRECTORY(rmi) ADD_SUBDIRECTORY(sdk) -ADD_SUBDIRECTORY(transport) # policy ADD_SUBDIRECTORY(policy) diff --git a/src/vist/rmi/CMakeLists.txt b/src/vist/rmi/CMakeLists.txt index 01b8e67..3ae4076 100644 --- a/src/vist/rmi/CMakeLists.txt +++ b/src/vist/rmi/CMakeLists.txt @@ -13,7 +13,13 @@ # limitations under the License ADD_VIST_COMMON_LIBRARY(vist_rmi gateway.cpp - remote.cpp) + remote.cpp + message.cpp) + +ADD_VIST_COMMON_LIBRARY(vist_rmi_impl impl/protocol.cpp) FILE(GLOB RMI_TESTS "tests/*.cpp") ADD_VIST_TEST(${RMI_TESTS}) + +FILE(GLOB RMI_IMPL_TESTS "impl/tests/*.cpp") +ADD_VIST_TEST(${RMI_IMPL_TESTS}) diff --git a/src/vist/rmi/gateway.cpp b/src/vist/rmi/gateway.cpp index 7654d1c..a7f6ab4 100644 --- a/src/vist/rmi/gateway.cpp +++ b/src/vist/rmi/gateway.cpp @@ -13,25 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License */ -/* - * @file gateway.cpp - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @author Jaemin Ryu (jm77.ryu@samsung.com) - * @brief Implementation of Server-side stub for exposing method. - */ #include "gateway.hpp" #include -#include -#include +#include +#include #include namespace vist { namespace rmi { -using namespace vist::transport; +using namespace vist::rmi::impl; class Gateway::Impl { public: diff --git a/src/vist/rmi/gateway.hpp b/src/vist/rmi/gateway.hpp index e1195d9..0b8ff8c 100644 --- a/src/vist/rmi/gateway.hpp +++ b/src/vist/rmi/gateway.hpp @@ -13,12 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License */ -/* - * @file gateway.hpp - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @author Jaemin Ryu (jm77.ryu@samsung.com) - * @brief Server-side stub for exposing method. - */ #pragma once diff --git a/src/vist/rmi/impl/client.hpp b/src/vist/rmi/impl/client.hpp new file mode 100644 index 0000000..c9186e8 --- /dev/null +++ b/src/vist/rmi/impl/client.hpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2019 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 + */ + +#pragma once + +#include "protocol.hpp" + +#include +#include + +namespace vist { +namespace rmi { +namespace impl { + +using boost::asio::local::stream_protocol; + +class Client { +public: + Client(const std::string& path) : socket(this->context) + { + try { + this->socket.connect(Protocol::Endpoint(path)); + } catch(const std::exception& e) { + ERROR(VIST) << "Failed to connect socket: " << e.what(); + std::rethrow_exception(std::current_exception()); + } + } + + inline Message request(Message& message) + { + return Protocol::Request(this->socket, message); + } + +private: + Protocol::Context context; + Protocol::Socket socket; +}; + +} // namespace impl +} // namespace rmi +} // namespace vist diff --git a/src/vist/rmi/impl/protocol.cpp b/src/vist/rmi/impl/protocol.cpp new file mode 100644 index 0000000..82c49b0 --- /dev/null +++ b/src/vist/rmi/impl/protocol.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2019 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 + */ + +#include "protocol.hpp" + +#include +#include + +namespace vist { +namespace rmi { +namespace impl { + +Message Protocol::Recv(Socket& socket) +{ + DEBUG(VIST) << "Socket read event occured."; + Message::Header header; + const auto& headerBuffer = boost::asio::buffer(&header, sizeof(Message::Header)); + auto readen = boost::asio::read(socket, headerBuffer); + if (readen != sizeof(Message::Header)) + THROW(ErrCode::ProtocolBroken) << "Failed to receive message header."; + + Message content(header); + const auto& contentBuffer = boost::asio::buffer(content.getBuffer()); + readen = boost::asio::read(socket, contentBuffer); + if (readen != content.size()) + THROW(ErrCode::ProtocolBroken) << "Failed to receive message content."; + + content.disclose(content.signature); + + return content; +} + +void Protocol::Send(Socket& socket, Message& message) +{ + DEBUG(VIST) << "Socket write event occured."; + const auto& headerBuffer = boost::asio::buffer(&message.header, + sizeof(Message::Header)); + auto written = boost::asio::write(socket, headerBuffer); + if (written != sizeof(Message::Header)) + THROW(ErrCode::ProtocolBroken) << "Failed to send message header."; + + const auto& contentBuffer = boost::asio::buffer(message.getBuffer(), message.size()); + written = boost::asio::write(socket, contentBuffer); + if (written != message.size()) + THROW(ErrCode::ProtocolBroken) << "Failed to send message content."; +} + +Message Protocol::Request(Socket& socket, Message& message) +{ + Protocol::Send(socket, message); + return Protocol::Recv(socket); +} + +void Protocol::Async::dispatch(const Task& task, std::atomic& polling) +{ + polling = true; + auto self = shared_from_this(); + const auto& header = boost::asio::buffer(&this->message.header, + sizeof(Message::Header)); + auto handler = [self, task, &polling](const auto& error, std::size_t size) { + if (error) { + if (error == boost::asio::error::eof) { + DEBUG(VIST) << "Socket EoF event occured."; + return; + } else { + THROW(ErrCode::RuntimeError) << error.message(); + } + } + + if (size != sizeof(Message::Header)) + THROW(ErrCode::ProtocolBroken) << error.message(); + + /// Resize message buffer to revieved header length. + self->message.resize(self->message.size()); + + const auto& contentBuffer = boost::asio::buffer(self->message.getBuffer()); + auto readen = boost::asio::read(self->socket, contentBuffer); + if (readen != self->message.size()) + THROW(ErrCode::ProtocolBroken) << "Failed to receive message content." + << readen << ", " << self->message.size(); + + self->message.disclose(self->message.signature); + self->process(task, polling); + }; + + boost::asio::async_read(self->socket, header, handler); +} + +void Protocol::Async::process(const Task& task, std::atomic& polling) +{ + bool raised = false; + std::string errMsg; + auto onError = [&raised, &errMsg](const std::string& message) { + ERROR(VIST) << "Failed to process task: " << message; + raised = true; + errMsg = message; + }; + + try { + /// Process dispatched task. + auto result = task(message); + this->message = result; + } catch (const vist::Exception& e) { + onError(e.what()); + } catch (const std::exception& e) { + onError(e.what()); + } + + if (raised) + this->message = Message(Message::Type::Error, errMsg); + + auto self = shared_from_this(); + const auto& headerBuffer = boost::asio::buffer(&this->message.header, + sizeof(Message::Header)); + auto handler = [self, task, &polling](const auto& error, std::size_t size) { + if (error || size != sizeof(Message::Header)) + THROW(ErrCode::ProtocolBroken) << "Failed to send message header: " + << error.message(); + + const auto& contentBuffer = boost::asio::buffer(self->message.getBuffer()); + auto written = boost::asio::write(self->socket, contentBuffer); + if (written != self->message.size()) + THROW(ErrCode::ProtocolBroken) << "Failed to send message content."; + + /// Re-dispatch for next request. + self->dispatch(task, polling); + }; + + boost::asio::async_write(self->socket, headerBuffer, handler); +} + +} // namespace impl +} // namespace rmi +} // namespace vist diff --git a/src/vist/rmi/impl/protocol.hpp b/src/vist/rmi/impl/protocol.hpp new file mode 100644 index 0000000..aa7ecf6 --- /dev/null +++ b/src/vist/rmi/impl/protocol.hpp @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019 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 + */ + +#pragma once + +#include + +#include +#include + +#include + +namespace vist { +namespace rmi { +namespace impl { + +struct Protocol { + using Acceptor = boost::asio::local::stream_protocol::acceptor; + using Context = boost::asio::io_service; + using Endpoint = boost::asio::local::stream_protocol::endpoint; + using Socket = boost::asio::local::stream_protocol::socket; + using Task = std::function; + + static Message Recv(Socket& socket); + static void Send(Socket& socket, Message& message); + + static Message Request(Socket& socket, Message& message); + + /// Passing shared_from_this() to lambda() guarantees + /// that the lambda() always refer to a live object. + class Async : public std::enable_shared_from_this { + public: + explicit Async(Context& context) : socket(context) {} + void dispatch(const Task& task, std::atomic& polling); + void process(const Task& task, std::atomic& polling); + + inline Socket& getSocket() + { + return this->socket; + } + + private: + Message message; + Socket socket; + }; +}; + +} // namespace impl +} // namespace rmi +} // namespace vist diff --git a/src/vist/rmi/impl/server.hpp b/src/vist/rmi/impl/server.hpp new file mode 100644 index 0000000..5e59b09 --- /dev/null +++ b/src/vist/rmi/impl/server.hpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019 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 + */ + +#pragma once + +#include "protocol.hpp" + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +namespace vist { +namespace rmi { +namespace impl { + +class Server { +public: + Server(const std::string& path, const Protocol::Task& task) : polling(false) + { + errno = 0; + if (::unlink(path.c_str()) == -1 && errno != ENOENT) + THROW(ErrCode::RuntimeError) << "Failed to remove file."; + + this->acceptor = std::make_unique(this->context, + Protocol::Endpoint(path)); + this->accept(task); + } + + inline void accept(const Protocol::Task& task) + { + auto asyncSession = std::make_shared(this->context); + auto handler = [this, asyncSession, task](const auto& error) { + DEBUG(VIST) << "New session is accepted."; + + if (error) + THROW(ErrCode::RuntimeError) << error.message(); + + asyncSession->dispatch(task, this->polling); + + this->accept(task); + }; + this->acceptor->async_accept(asyncSession->getSocket(), handler); + } + + inline void run(unsigned int timeout = 0, Timer::Predicate condition = nullptr) + { + if (timeout > 0) { + auto stopper = [this]() { + INFO(VIST) << "There are no sessions. And timeout is occured."; + this->context.stop(); + }; + + auto wrapper = [this, condition]() -> bool { + if (condition) + return condition() && polling == false; + + return polling == false; + }; + + Timer::ExecOnce(stopper, wrapper, timeout); + } + + this->context.run(); + } + + inline void stop() + { + this->context.stop(); + } + +private: + Protocol::Context context; + std::unique_ptr acceptor; + + /// check for session is maintained + std::atomic polling; +}; + +} // namespace impl +} // namespace rmi +} // namespace vist diff --git a/src/vist/rmi/impl/tests/protocol.cpp b/src/vist/rmi/impl/tests/protocol.cpp new file mode 100644 index 0000000..2b2e4ac --- /dev/null +++ b/src/vist/rmi/impl/tests/protocol.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2019 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 + */ + +#include +#include + +#include +#include + +#include +#include + +#include + +using namespace vist::rmi; +using namespace vist::rmi::impl; +using boost::asio::local::stream_protocol; + +namespace { + +/// Request variables +std::string requestSignature = "request signature"; +int request1 = 100; +bool request2 = true; +std::string request3 = "request argument"; + +/// Response variables +std::string responseSignature = "response signature"; +int response1 = 300; +bool response2 = false; +std::string response3 = "response argument"; + +} // anonymous namespace + +TEST(ProtocolTests, sync_server_sync_client) +{ + std::string sockPath = "vist-test.sock"; + ::unlink(sockPath.c_str()); + + /// Server configuration + boost::asio::io_service context; + stream_protocol::acceptor acceptor(context, stream_protocol::endpoint(sockPath)); + stream_protocol::socket sock(context); + + auto handler = [&](const auto& error) { + EXPECT_EQ(error, boost::system::errc::success); + + Message request = Protocol::Recv(sock); + EXPECT_EQ(request.signature, requestSignature); + + int recv1; + bool recv2; + std::string recv3; + request.disclose(recv1, recv2, recv3); + EXPECT_EQ(request1, recv1); + EXPECT_EQ(request2, recv2); + EXPECT_EQ(request3, recv3); + + Message reply(Message::Type::Reply, responseSignature); + reply.enclose(response1, response2, response3); + Protocol::Send(sock, reply); + }; + acceptor.async_accept(sock, handler); + + auto serverThread = std::thread([&]() { + context.run(); + }); + + { /// Client configuration + boost::asio::io_service context; + stream_protocol::socket sock(context); + sock.connect(stream_protocol::endpoint(sockPath)); + + Message request(Message::Type::MethodCall, requestSignature); + request.enclose(request1, request2, request3); + + auto reply = Protocol::Request(sock, request); + EXPECT_EQ(reply.signature, responseSignature); + + int recv1; + bool recv2; + std::string recv3; + reply.disclose(recv1, recv2, recv3); + EXPECT_EQ(response1, recv1); + EXPECT_EQ(response2, recv2); + EXPECT_EQ(response3, recv3); + } + + context.stop(); + + if (serverThread.joinable()) + serverThread.join(); +} + +/* example without polling memeber variable +TEST(ProtocolTests, async_server_sync_client) +{ + std::string sockPath = "vist-test.sock"; + ::unlink(sockPath.c_str()); + + /// Server configuration + boost::asio::io_service context; + stream_protocol::acceptor acceptor(context, stream_protocol::endpoint(sockPath)); + + auto async = std::make_shared(context); + auto handler = [&](const auto& error) { + EXPECT_EQ(error, boost::system::errc::success); + auto task = [&](auto& message) -> Message { + EXPECT_EQ(message.signature, requestSignature); + + int recv1; + bool recv2; + std::string recv3; + message.disclose(recv1, recv2, recv3); + EXPECT_EQ(request1, recv1); + EXPECT_EQ(request2, recv2); + EXPECT_EQ(request3, recv3); + + Message reply(Message::Type::Reply, responseSignature); + reply.enclose(response1, response2, response3); + return reply; + }; + + async->dispatch(task); + }; + acceptor.async_accept(async->getSocket(), handler); + + auto serverThread = std::thread([&]() { + context.run(); + }); + + { /// Client configuration + boost::asio::io_service context; + stream_protocol::socket sock(context); + sock.connect(stream_protocol::endpoint(sockPath)); + + Message request(Message::Type::MethodCall, requestSignature); + request.enclose(request1, request2, request3); + + auto requestClosure = [&]() { + auto reply = Protocol::Request(sock, request); + EXPECT_EQ(reply.signature, responseSignature); + + int recv1; + bool recv2; + std::string recv3; + reply.disclose(recv1, recv2, recv3); + EXPECT_EQ(response1, recv1); + EXPECT_EQ(response2, recv2); + EXPECT_EQ(response3, recv3); + }; + + for (int i = 0; i < 3; i++) + requestClosure(); + } + + context.stop(); + + if (serverThread.joinable()) + serverThread.join(); +} +*/ diff --git a/src/vist/rmi/impl/tests/server-client.cpp b/src/vist/rmi/impl/tests/server-client.cpp new file mode 100644 index 0000000..17058cb --- /dev/null +++ b/src/vist/rmi/impl/tests/server-client.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2019 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 + */ + +#include +#include +#include + +#include +#include + +#include + +#include + +using namespace vist::rmi; +using namespace vist::rmi::impl; +using boost::asio::local::stream_protocol; + +namespace { + +/// Request variables +std::string requestSignature = "request signature"; +int request1 = 100; +bool request2 = true; +std::string request3 = "request argument"; + +/// Response variables +std::string responseSignature = "response signature"; +int response1 = 300; +bool response2 = false; +std::string response3 = "response argument"; + +} // anonymous namespace + +TEST(ServerClientTests, server) +{ + std::string sockPath = "vist-test.sock"; + + auto task = [&](Message& message) -> Message { + EXPECT_EQ(message.signature, requestSignature); + + int recv1; + bool recv2; + std::string recv3; + message.disclose(recv1, recv2, recv3); + EXPECT_EQ(request1, recv1); + EXPECT_EQ(request2, recv2); + EXPECT_EQ(request3, recv3); + + Message reply(Message::Type::Reply, responseSignature); + reply.enclose(response1, response2, response3); + return reply; + }; + + Server server(sockPath, task); + auto serverThread = std::thread([&]() { + server.run(); + }); + + { /// Client configuration + auto clientClosure = [&]() { + Client client(sockPath); + + Message message(Message::Type::MethodCall, requestSignature); + message.enclose(request1, request2, request3); + + for (int i = 0; i < 3; i++) { + auto reply = client.request(message); + EXPECT_EQ(reply.signature, responseSignature); + + int recv1; + bool recv2; + std::string recv3; + reply.disclose(recv1, recv2, recv3); + EXPECT_EQ(response1, recv1); + EXPECT_EQ(response2, recv2); + EXPECT_EQ(response3, recv3); + } + }; + + for (int i = 0; i < 3; i++) + clientClosure(); + } + + server.stop(); + + if (serverThread.joinable()) + serverThread.join(); +} diff --git a/src/vist/rmi/message.cpp b/src/vist/rmi/message.cpp new file mode 100644 index 0000000..86902c6 --- /dev/null +++ b/src/vist/rmi/message.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2018-present 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 + */ + +#include "message.hpp" + +namespace vist { +namespace rmi { + +Message::Message(unsigned int type, const std::string& signature) : + header({0, type, signature.size()}), + signature(signature) +{ + this->enclose(signature); +} + +Message::Message(Header header) : header(header) +{ + this->buffer.resize(this->header.length); +} + +bool Message::success() const noexcept +{ + return !error(); +} + +bool Message::error() const noexcept +{ + return this->header.type == Type::Error; +} + +std::string Message::what() const noexcept +{ + return this->signature; +} + +std::size_t Message::size(void) const noexcept +{ + return this->header.length; +} + +void Message::resize(std::size_t size) +{ + this->buffer.resize(size); +} + +std::vector& Message::getBuffer(void) noexcept +{ + return this->buffer.getBuffer(); +} + +} // namespace rmi +} // namespace vist diff --git a/src/vist/rmi/message.hpp b/src/vist/rmi/message.hpp new file mode 100644 index 0000000..4aca730 --- /dev/null +++ b/src/vist/rmi/message.hpp @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2018-present 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 + */ + +#pragma once + +#include +#include + +#include + +namespace vist { +namespace rmi { + +struct Message final { + enum Type : unsigned int { + Invalid, + MethodCall, + Reply, + Error, + Signal + }; + + struct Header { + unsigned int id; + unsigned int type; + size_t length; + }; + + explicit Message(void) = default; + explicit Message(unsigned int type, const std::string& signature); + explicit Message(Header header); + + ~Message(void) noexcept = default; + + Message(const Message&) = default; + Message(Message&&) = default; + + Message& operator=(const Message&) = default; + Message& operator=(Message&&) = default; + + template + void enclose(Args&&... args); + template + void disclose(Args&... args); + + bool success() const noexcept; + bool error() const noexcept; + std::string what() const noexcept; + + std::size_t size(void) const noexcept; + void resize(std::size_t size); + std::vector& getBuffer(void) noexcept; + + Header header; + std::string signature; + Archive buffer; +}; + +template +void Message::enclose(Args&&... args) +{ + this->buffer.pack(std::forward(args)...); + header.length = this->buffer.size(); +} + +template +void Message::disclose(Args&... args) +{ + this->buffer.unpack(args...); +} + +} // namespace rmi +} // namespace vist diff --git a/src/vist/rmi/remote.cpp b/src/vist/rmi/remote.cpp index 6ea77d7..d2ff1e6 100644 --- a/src/vist/rmi/remote.cpp +++ b/src/vist/rmi/remote.cpp @@ -13,16 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License */ -/* - * @file remote.cpp - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @author Jaemin Ryu (jm77.ryu@samsung.com) - * @brief Implementation of remote. - */ #include "remote.hpp" -#include +#include #include #include @@ -30,7 +24,7 @@ namespace vist { namespace rmi { -using namespace vist::transport; +using namespace vist::rmi::impl; class Remote::Impl { public: diff --git a/src/vist/rmi/remote.hpp b/src/vist/rmi/remote.hpp index 4dd64f4..5896e39 100644 --- a/src/vist/rmi/remote.hpp +++ b/src/vist/rmi/remote.hpp @@ -13,17 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License */ -/* - * @file remote.hpp - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @author Jaemin Ryu (jm77.ryu@samsung.com) - * @brief Client-side stub for invoking remote method. - */ #pragma once #include -#include +#include #include #include @@ -33,8 +27,6 @@ namespace vist { namespace rmi { -using namespace vist::transport; - class Remote final { public: explicit Remote(const std::string& path); diff --git a/src/vist/rmi/tests/rmi.cpp b/src/vist/rmi/tests/rmi.cpp index d73663e..c5de56f 100644 --- a/src/vist/rmi/tests/rmi.cpp +++ b/src/vist/rmi/tests/rmi.cpp @@ -13,12 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License */ -/* - * @file rmi.cpp - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @brief Testcases of rmi. - */ - #include #include diff --git a/src/vist/transport/CMakeLists.txt b/src/vist/transport/CMakeLists.txt deleted file mode 100644 index 451f12a..0000000 --- a/src/vist/transport/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2019 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 - -ADD_VIST_COMMON_LIBRARY(vist_transport message.cpp - protocol.cpp) - -FILE(GLOB TRANSPORT_TESTS "tests/*.cpp") -ADD_VIST_TEST(${TRANSPORT_TESTS}) diff --git a/src/vist/transport/client.hpp b/src/vist/transport/client.hpp deleted file mode 100644 index 1f2091b..0000000 --- a/src/vist/transport/client.hpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2019 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 client.hpp - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @brief Protocol compliant client. - */ - -#pragma once - -#include -#include -#include - -namespace vist { -namespace transport { - -using boost::asio::local::stream_protocol; - -class Client { -public: - Client(const std::string& path) : socket(this->context) - { - try { - this->socket.connect(Protocol::Endpoint(path)); - } catch(const std::exception& e) { - ERROR(VIST) << "Failed to connect socket: " << e.what(); - std::rethrow_exception(std::current_exception()); - } - } - - inline Message request(Message& message) - { - return Protocol::Request(this->socket, message); - } - -private: - Protocol::Context context; - Protocol::Socket socket; -}; - -} // namespace transport -} // namespace vist diff --git a/src/vist/transport/message.cpp b/src/vist/transport/message.cpp deleted file mode 100644 index 3153cd6..0000000 --- a/src/vist/transport/message.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2018-present 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 message.cpp - * @author Jaemin Ryu (jm77.ryu@samsung.com) - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @brief Implementaion of message. - */ - -#include "message.hpp" - -namespace vist { -namespace transport { - -Message::Message(unsigned int type, const std::string& signature) : - header({0, type, signature.size()}), - signature(signature) -{ - this->enclose(signature); -} - -Message::Message(Header header) : header(header) -{ - this->buffer.resize(this->header.length); -} - -bool Message::success() const noexcept -{ - return !error(); -} - -bool Message::error() const noexcept -{ - return this->header.type == Type::Error; -} - -std::string Message::what() const noexcept -{ - return this->signature; -} - -std::size_t Message::size(void) const noexcept -{ - return this->header.length; -} - -void Message::resize(std::size_t size) -{ - this->buffer.resize(size); -} - -std::vector& Message::getBuffer(void) noexcept -{ - return this->buffer.getBuffer(); -} - -} // namespace transport -} // namespace vist diff --git a/src/vist/transport/message.hpp b/src/vist/transport/message.hpp deleted file mode 100644 index 55dd5b5..0000000 --- a/src/vist/transport/message.hpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2018-present 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 message.hpp - * @author Jaemin Ryu (jm77.ryu@samsung.com) - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @brief The unit of socket communication. - */ - -#pragma once - -#include -#include - -#include - -namespace vist { -namespace transport { - -struct Message final { - enum Type : unsigned int { - Invalid, - MethodCall, - Reply, - Error, - Signal - }; - - struct Header { - unsigned int id; - unsigned int type; - size_t length; - }; - - explicit Message(void) = default; - explicit Message(unsigned int type, const std::string& signature); - explicit Message(Header header); - - ~Message(void) noexcept = default; - - Message(const Message&) = default; - Message(Message&&) = default; - - Message& operator=(const Message&) = default; - Message& operator=(Message&&) = default; - - template - void enclose(Args&&... args); - template - void disclose(Args&... args); - - bool success() const noexcept; - bool error() const noexcept; - std::string what() const noexcept; - - std::size_t size(void) const noexcept; - void resize(std::size_t size); - std::vector& getBuffer(void) noexcept; - - Header header; - std::string signature; - Archive buffer; -}; - -template -void Message::enclose(Args&&... args) -{ - this->buffer.pack(std::forward(args)...); - header.length = this->buffer.size(); -} - -template -void Message::disclose(Args&... args) -{ - this->buffer.unpack(args...); -} - -} // namespace transport -} // namespace vist diff --git a/src/vist/transport/protocol.cpp b/src/vist/transport/protocol.cpp deleted file mode 100644 index 88fb9ff..0000000 --- a/src/vist/transport/protocol.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2019 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 - */ - -#include "protocol.hpp" - -#include -#include - -namespace vist { -namespace transport { - -Message Protocol::Recv(Socket& socket) -{ - DEBUG(VIST) << "Socket read event occured."; - Message::Header header; - const auto& headerBuffer = boost::asio::buffer(&header, sizeof(Message::Header)); - auto readen = boost::asio::read(socket, headerBuffer); - if (readen != sizeof(Message::Header)) - THROW(ErrCode::ProtocolBroken) << "Failed to receive message header."; - - Message content(header); - const auto& contentBuffer = boost::asio::buffer(content.getBuffer()); - readen = boost::asio::read(socket, contentBuffer); - if (readen != content.size()) - THROW(ErrCode::ProtocolBroken) << "Failed to receive message content."; - - content.disclose(content.signature); - - return content; -} - -void Protocol::Send(Socket& socket, Message& message) -{ - DEBUG(VIST) << "Socket write event occured."; - const auto& headerBuffer = boost::asio::buffer(&message.header, - sizeof(Message::Header)); - auto written = boost::asio::write(socket, headerBuffer); - if (written != sizeof(Message::Header)) - THROW(ErrCode::ProtocolBroken) << "Failed to send message header."; - - const auto& contentBuffer = boost::asio::buffer(message.getBuffer(), message.size()); - written = boost::asio::write(socket, contentBuffer); - if (written != message.size()) - THROW(ErrCode::ProtocolBroken) << "Failed to send message content."; -} - -Message Protocol::Request(Socket& socket, Message& message) -{ - Protocol::Send(socket, message); - return Protocol::Recv(socket); -} - -void Protocol::Async::dispatch(const Task& task, std::atomic& polling) -{ - polling = true; - auto self = shared_from_this(); - const auto& header = boost::asio::buffer(&this->message.header, - sizeof(Message::Header)); - auto handler = [self, task, &polling](const auto& error, std::size_t size) { - if (error) { - if (error == boost::asio::error::eof) { - DEBUG(VIST) << "Socket EoF event occured."; - return; - } else { - THROW(ErrCode::RuntimeError) << error.message(); - } - } - - if (size != sizeof(Message::Header)) - THROW(ErrCode::ProtocolBroken) << error.message(); - - /// Resize message buffer to revieved header length. - self->message.resize(self->message.size()); - - const auto& contentBuffer = boost::asio::buffer(self->message.getBuffer()); - auto readen = boost::asio::read(self->socket, contentBuffer); - if (readen != self->message.size()) - THROW(ErrCode::ProtocolBroken) << "Failed to receive message content." - << readen << ", " << self->message.size(); - - self->message.disclose(self->message.signature); - self->process(task, polling); - }; - - boost::asio::async_read(self->socket, header, handler); -} - -void Protocol::Async::process(const Task& task, std::atomic& polling) -{ - bool raised = false; - std::string errMsg; - auto onError = [&raised, &errMsg](const std::string& message) { - ERROR(VIST) << "Failed to process task: " << message; - raised = true; - errMsg = message; - }; - - try { - /// Process dispatched task. - auto result = task(message); - this->message = result; - } catch (const vist::Exception& e) { - onError(e.what()); - } catch (const std::exception& e) { - onError(e.what()); - } - - if (raised) - this->message = Message(Message::Type::Error, errMsg); - - auto self = shared_from_this(); - const auto& headerBuffer = boost::asio::buffer(&this->message.header, - sizeof(Message::Header)); - auto handler = [self, task, &polling](const auto& error, std::size_t size) { - if (error || size != sizeof(Message::Header)) - THROW(ErrCode::ProtocolBroken) << "Failed to send message header: " - << error.message(); - - const auto& contentBuffer = boost::asio::buffer(self->message.getBuffer()); - auto written = boost::asio::write(self->socket, contentBuffer); - if (written != self->message.size()) - THROW(ErrCode::ProtocolBroken) << "Failed to send message content."; - - /// Re-dispatch for next request. - self->dispatch(task, polling); - }; - - boost::asio::async_write(self->socket, headerBuffer, handler); -} - -} // namespace transport -} // namespace vist diff --git a/src/vist/transport/protocol.hpp b/src/vist/transport/protocol.hpp deleted file mode 100644 index 877dd76..0000000 --- a/src/vist/transport/protocol.hpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2019 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 protocol.hpp - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @brief Socket communication protocol between server and client. - */ - -#pragma once - -#include - -#include -#include - -#include - -namespace vist { -namespace transport { - -struct Protocol { - using Acceptor = boost::asio::local::stream_protocol::acceptor; - using Context = boost::asio::io_service; - using Endpoint = boost::asio::local::stream_protocol::endpoint; - using Socket = boost::asio::local::stream_protocol::socket; - using Task = std::function; - - static Message Recv(Socket& socket); - static void Send(Socket& socket, Message& message); - - static Message Request(Socket& socket, Message& message); - - /// Passing shared_from_this() to lambda() guarantees - /// that the lambda() always refer to a live object. - class Async : public std::enable_shared_from_this { - public: - explicit Async(Context& context) : socket(context) {} - void dispatch(const Task& task, std::atomic& polling); - void process(const Task& task, std::atomic& polling); - - inline Socket& getSocket() - { - return this->socket; - } - - private: - Message message; - Socket socket; - }; -}; - -} // namespace transport -} // namespace vist diff --git a/src/vist/transport/server.hpp b/src/vist/transport/server.hpp deleted file mode 100644 index afb22d8..0000000 --- a/src/vist/transport/server.hpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2019 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 server.hpp - * @author Sangwan Kwon (sangwan.kwon@samsung.com) - * @brief Protocol compliant server. - */ - -#pragma once - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -namespace vist { -namespace transport { - -class Server { -public: - Server(const std::string& path, const Protocol::Task& task) : polling(false) - { - errno = 0; - if (::unlink(path.c_str()) == -1 && errno != ENOENT) - THROW(ErrCode::RuntimeError) << "Failed to remove file."; - - this->acceptor = std::make_unique(this->context, - Protocol::Endpoint(path)); - this->accept(task); - } - - inline void accept(const Protocol::Task& task) - { - auto asyncSession = std::make_shared(this->context); - auto handler = [this, asyncSession, task](const auto& error) { - DEBUG(VIST) << "New session is accepted."; - - if (error) - THROW(ErrCode::RuntimeError) << error.message(); - - asyncSession->dispatch(task, this->polling); - - this->accept(task); - }; - this->acceptor->async_accept(asyncSession->getSocket(), handler); - } - - inline void run(unsigned int timeout = 0, Timer::Predicate condition = nullptr) - { - if (timeout > 0) { - auto stopper = [this]() { - INFO(VIST) << "There are no sessions. And timeout is occured."; - this->context.stop(); - }; - - auto wrapper = [this, condition]() -> bool { - if (condition) - return condition() && polling == false; - - return polling == false; - }; - - Timer::ExecOnce(stopper, wrapper, timeout); - } - - this->context.run(); - } - - inline void stop() - { - this->context.stop(); - } - -private: - Protocol::Context context; - std::unique_ptr acceptor; - - /// check for session is maintained - std::atomic polling; -}; - -} // namespace transport -} // namespace vist diff --git a/src/vist/transport/systemd-socket.hpp b/src/vist/transport/systemd-socket.hpp deleted file mode 100644 index 4d768ed..0000000 --- a/src/vist/transport/systemd-socket.hpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2019 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 - */ - -#pragma once - -#include -#include - -#include - -namespace vist { -namespace transport { - -class SystemdSocket { -public: - static int Create(const std::string& path) - { - static int fds = -1; - - if (fds == -1) - fds = ::sd_listen_fds(0); - - if (fds < 0) - THROW(ErrCode::RuntimeError) << "Failed to get listened systemd fds."; - - for (int fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fds; ++fd) { - if (::sd_is_socket_unix(fd, SOCK_STREAM, 1, path.c_str(), 0) > 0) { - INFO(VIST) << "Systemd socket of service is found with fd: " << fd; - return fd; - } - } - - THROW(ErrCode::RuntimeError) << "Failed to find listened systemd fds."; - } -}; - -} // namespace transport -} // namespace vist diff --git a/src/vist/transport/tests/protocol.cpp b/src/vist/transport/tests/protocol.cpp deleted file mode 100644 index 94262a9..0000000 --- a/src/vist/transport/tests/protocol.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2019 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 - */ - -#include - -#include -#include - -#include -#include - -#include - -using namespace vist::transport; -using boost::asio::local::stream_protocol; - -namespace { - -/// Request variables -std::string requestSignature = "request signature"; -int request1 = 100; -bool request2 = true; -std::string request3 = "request argument"; - -/// Response variables -std::string responseSignature = "response signature"; -int response1 = 300; -bool response2 = false; -std::string response3 = "response argument"; - -} // anonymous namespace - -TEST(ProtocolTests, sync_server_sync_client) -{ - std::string sockPath = "vist-test.sock"; - ::unlink(sockPath.c_str()); - - /// Server configuration - boost::asio::io_service context; - stream_protocol::acceptor acceptor(context, stream_protocol::endpoint(sockPath)); - stream_protocol::socket sock(context); - - auto handler = [&](const auto& error) { - EXPECT_EQ(error, boost::system::errc::success); - - Message request = Protocol::Recv(sock); - EXPECT_EQ(request.signature, requestSignature); - - int recv1; - bool recv2; - std::string recv3; - request.disclose(recv1, recv2, recv3); - EXPECT_EQ(request1, recv1); - EXPECT_EQ(request2, recv2); - EXPECT_EQ(request3, recv3); - - Message reply(Message::Type::Reply, responseSignature); - reply.enclose(response1, response2, response3); - Protocol::Send(sock, reply); - }; - acceptor.async_accept(sock, handler); - - auto serverThread = std::thread([&]() { - context.run(); - }); - - { /// Client configuration - boost::asio::io_service context; - stream_protocol::socket sock(context); - sock.connect(stream_protocol::endpoint(sockPath)); - - Message request(Message::Type::MethodCall, requestSignature); - request.enclose(request1, request2, request3); - - auto reply = Protocol::Request(sock, request); - EXPECT_EQ(reply.signature, responseSignature); - - int recv1; - bool recv2; - std::string recv3; - reply.disclose(recv1, recv2, recv3); - EXPECT_EQ(response1, recv1); - EXPECT_EQ(response2, recv2); - EXPECT_EQ(response3, recv3); - } - - context.stop(); - - if (serverThread.joinable()) - serverThread.join(); -} - -/* example without polling memeber variable -TEST(ProtocolTests, async_server_sync_client) -{ - std::string sockPath = "vist-test.sock"; - ::unlink(sockPath.c_str()); - - /// Server configuration - boost::asio::io_service context; - stream_protocol::acceptor acceptor(context, stream_protocol::endpoint(sockPath)); - - auto async = std::make_shared(context); - auto handler = [&](const auto& error) { - EXPECT_EQ(error, boost::system::errc::success); - auto task = [&](auto& message) -> Message { - EXPECT_EQ(message.signature, requestSignature); - - int recv1; - bool recv2; - std::string recv3; - message.disclose(recv1, recv2, recv3); - EXPECT_EQ(request1, recv1); - EXPECT_EQ(request2, recv2); - EXPECT_EQ(request3, recv3); - - Message reply(Message::Type::Reply, responseSignature); - reply.enclose(response1, response2, response3); - return reply; - }; - - async->dispatch(task); - }; - acceptor.async_accept(async->getSocket(), handler); - - auto serverThread = std::thread([&]() { - context.run(); - }); - - { /// Client configuration - boost::asio::io_service context; - stream_protocol::socket sock(context); - sock.connect(stream_protocol::endpoint(sockPath)); - - Message request(Message::Type::MethodCall, requestSignature); - request.enclose(request1, request2, request3); - - auto requestClosure = [&]() { - auto reply = Protocol::Request(sock, request); - EXPECT_EQ(reply.signature, responseSignature); - - int recv1; - bool recv2; - std::string recv3; - reply.disclose(recv1, recv2, recv3); - EXPECT_EQ(response1, recv1); - EXPECT_EQ(response2, recv2); - EXPECT_EQ(response3, recv3); - }; - - for (int i = 0; i < 3; i++) - requestClosure(); - } - - context.stop(); - - if (serverThread.joinable()) - serverThread.join(); -} -*/ diff --git a/src/vist/transport/tests/server-client.cpp b/src/vist/transport/tests/server-client.cpp deleted file mode 100644 index d76c6f9..0000000 --- a/src/vist/transport/tests/server-client.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2019 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 - */ - -#include -#include - -#include -#include - -#include - -#include - -using namespace vist::transport; -using boost::asio::local::stream_protocol; - -namespace { - -/// Request variables -std::string requestSignature = "request signature"; -int request1 = 100; -bool request2 = true; -std::string request3 = "request argument"; - -/// Response variables -std::string responseSignature = "response signature"; -int response1 = 300; -bool response2 = false; -std::string response3 = "response argument"; - -} // anonymous namespace - -TEST(ServerClientTests, server) -{ - std::string sockPath = "vist-test.sock"; - - auto task = [&](Message& message) -> Message { - EXPECT_EQ(message.signature, requestSignature); - - int recv1; - bool recv2; - std::string recv3; - message.disclose(recv1, recv2, recv3); - EXPECT_EQ(request1, recv1); - EXPECT_EQ(request2, recv2); - EXPECT_EQ(request3, recv3); - - Message reply(Message::Type::Reply, responseSignature); - reply.enclose(response1, response2, response3); - return reply; - }; - - Server server(sockPath, task); - auto serverThread = std::thread([&]() { - server.run(); - }); - - { /// Client configuration - auto clientClosure = [&]() { - Client client(sockPath); - - Message message(Message::Type::MethodCall, requestSignature); - message.enclose(request1, request2, request3); - - for (int i = 0; i < 3; i++) { - auto reply = client.request(message); - EXPECT_EQ(reply.signature, responseSignature); - - int recv1; - bool recv2; - std::string recv3; - reply.disclose(recv1, recv2, recv3); - EXPECT_EQ(response1, recv1); - EXPECT_EQ(response2, recv2); - EXPECT_EQ(response3, recv3); - } - }; - - for (int i = 0; i < 3; i++) - clientClosure(); - } - - server.stop(); - - if (serverThread.joinable()) - serverThread.join(); -}