From 0835cbb5a4be5898ce08d01f11e662009657626a Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Thu, 9 Oct 2014 14:44:42 +0200 Subject: [PATCH 01/16] Implement agent protocol layer This patch contains implementation of (de)serializer class for agent protocol. Change-Id: I8ac7b5816545bd8e76a50d66a84b8ac686125985 --- src/common/protocol/ProtocolAgent.cpp | 126 ++++++++++++++++++++++++++++++---- src/common/protocol/ProtocolAgent.h | 10 ++- src/common/protocol/ProtocolOpCode.h | 8 +++ 3 files changed, 130 insertions(+), 14 deletions(-) diff --git a/src/common/protocol/ProtocolAgent.cpp b/src/common/protocol/ProtocolAgent.cpp index 7d85d31..7ccec81 100644 --- a/src/common/protocol/ProtocolAgent.cpp +++ b/src/common/protocol/ProtocolAgent.cpp @@ -23,12 +23,16 @@ #include #include -#include #include #include #include #include #include +#include +#include +#include +#include +#include #include "ProtocolAgent.h" @@ -44,6 +48,29 @@ ProtocolPtr ProtocolAgent::clone(void) { return std::make_shared(); } +RequestPtr ProtocolAgent::deserializeActionRequest(void) { + AgentRequestType requestType; + RawBuffer data; + + ProtocolDeserialization::deserialize(m_frameHeader, requestType); + ProtocolDeserialization::deserialize(m_frameHeader, data); + + LOGD("Deserialized AgentActionRequest: requestType [%" PRIu8 "], data lengtgh <%zu>", + requestType, data.size()); + + return std::make_shared(requestType, data, m_frameHeader.sequenceNumber()); +} + +RequestPtr ProtocolAgent::deserializeRegisterRequest(void) { + AgentType agentType; + + ProtocolDeserialization::deserialize(m_frameHeader, agentType); + + LOGD("Deserialized AgentRegisterRequest: agent type <%s>", agentType.c_str()); + + return std::make_shared(agentType, m_frameHeader.sequenceNumber()); +} + RequestPtr ProtocolAgent::extractRequestFromBuffer(BinaryQueuePtr bufferQueue) { ProtocolFrameSerializer::deserializeHeader(m_frameHeader, bufferQueue); @@ -54,15 +81,44 @@ RequestPtr ProtocolAgent::extractRequestFromBuffer(BinaryQueuePtr bufferQueue) { ProtocolDeserialization::deserialize(m_frameHeader, opCode); LOGD("Deserialized opCode [%" PRIu8 "]", opCode); switch (opCode) { - default: - throw InvalidProtocolException(InvalidProtocolException::WrongOpCode); - break; + case OpAgentActionRequest: + return deserializeActionRequest(); + case OpAgentRegisterRequest: + return deserializeRegisterRequest(); + default: + throw InvalidProtocolException(InvalidProtocolException::WrongOpCode); + break; } } return nullptr; } +ResponsePtr ProtocolAgent::deserializeActionResponse(void) { + AgentResponseType responseType; + RawBuffer data; + + ProtocolDeserialization::deserialize(m_frameHeader, responseType); + ProtocolDeserialization::deserialize(m_frameHeader, data); + + LOGD("Deserialized AgentActionResponse: responseType [%" PRIu8 "], data lengtgh <%zu>", + responseType, data.size()); + + return std::make_shared(responseType, data, + m_frameHeader.sequenceNumber()); +} + +ResponsePtr ProtocolAgent::deserializeRegisterResponse(void) { + ProtocolResponseCode result; + + ProtocolDeserialization::deserialize(m_frameHeader, result); + + LOGD("Deserialized AgentRegisterResponse: result [%d]", static_cast(result)); + + return std::make_shared(static_cast(result), + m_frameHeader.sequenceNumber()); +} + ResponsePtr ProtocolAgent::extractResponseFromBuffer(BinaryQueuePtr bufferQueue) { ProtocolFrameSerializer::deserializeHeader(m_frameHeader, bufferQueue); @@ -73,23 +129,67 @@ ResponsePtr ProtocolAgent::extractResponseFromBuffer(BinaryQueuePtr bufferQueue) ProtocolDeserialization::deserialize(m_frameHeader, opCode); LOGD("Deserialized opCode [%" PRIu8 "]", opCode); switch (opCode) { - default: - throw InvalidProtocolException(InvalidProtocolException::WrongOpCode); - break; + case OpAgentActionResponse: + return deserializeActionResponse(); + case OpAgentRegisterResponse: + return deserializeRegisterResponse(); + default: + throw InvalidProtocolException(InvalidProtocolException::WrongOpCode); + break; } } return nullptr; } -void ProtocolAgent::execute(RequestContextPtr context UNUSED, - AgentActionRequestPtr request UNUSED) { - //TODO: implement +void ProtocolAgent::execute(RequestContextPtr context, AgentActionRequestPtr request) { + LOGD("Serializing AgentActionRequest: op [%" PRIu8 "], requestType [%" PRIu8 "], " + "data lengtgh <%zu>", OpAgentActionRequest, request->type(), request->data().size()); + + ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber()); + + ProtocolSerialization::serialize(frame, OpAgentActionRequest); + ProtocolSerialization::serialize(frame, request->type()); + ProtocolSerialization::serialize(frame, request->data()); + + ProtocolFrameSerializer::finishSerialization(frame, *context->responseQueue()); +} + +void ProtocolAgent::execute(RequestContextPtr context, AgentRegisterRequestPtr request) { + LOGD("Serializing AgentRegisterRequest: op [%" PRIu8 "], agent type <%s>", + OpAgentRegisterRequest, request->agentType().c_str()); + + ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber()); + + ProtocolSerialization::serialize(frame, OpAgentRegisterRequest); + ProtocolSerialization::serialize(frame, request->agentType()); + + ProtocolFrameSerializer::finishSerialization(frame, *context->responseQueue()); +} + +void ProtocolAgent::execute(RequestContextPtr context, AgentRegisterResponsePtr response) { + LOGD("Serializing AgentRegisterResponse: op [%" PRIu8 "], response code: [%d]", + OpAgentRegisterResponse, static_cast(response->m_code)); + + ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(response->sequenceNumber()); + + ProtocolSerialization::serialize(frame, OpAgentRegisterResponse); + ProtocolSerialization::serialize(frame, static_cast(response->m_code)); + + ProtocolFrameSerializer::finishSerialization(frame, *context->responseQueue()); } -void ProtocolAgent::execute(RequestContextPtr context UNUSED, - AgentActionResponsePtr request UNUSED) { - //TODO: implement +void ProtocolAgent::execute(RequestContextPtr context, AgentActionResponsePtr response) { + LOGD("Serializing AgentActionResponse: op [%" PRIu8 "], responseType [%" PRIu8 "], " + "data lengtgh <%zu>", OpAgentActionResponse, response->type(), response->data().size()); + + ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(response->sequenceNumber()); + + ProtocolSerialization::serialize(frame, OpAgentActionResponse); + ProtocolSerialization::serialize(frame, response->type()); + ProtocolSerialization::serialize(frame, response->data()); + + ProtocolFrameSerializer::finishSerialization(frame, *context->responseQueue()); } } // namespace Cynara diff --git a/src/common/protocol/ProtocolAgent.h b/src/common/protocol/ProtocolAgent.h index 92fb788..ca28ec7 100644 --- a/src/common/protocol/ProtocolAgent.h +++ b/src/common/protocol/ProtocolAgent.h @@ -42,7 +42,15 @@ public: virtual ResponsePtr extractResponseFromBuffer(BinaryQueuePtr bufferQueue); virtual void execute(RequestContextPtr context, AgentActionRequestPtr request); - virtual void execute(RequestContextPtr context, AgentActionResponsePtr response); + virtual void execute(RequestContextPtr context, AgentActionResponsePtr request); + virtual void execute(RequestContextPtr context, AgentRegisterRequestPtr request); + virtual void execute(RequestContextPtr context, AgentRegisterResponsePtr request); + +private: + RequestPtr deserializeActionRequest(void); + RequestPtr deserializeRegisterRequest(void); + ResponsePtr deserializeActionResponse(void); + ResponsePtr deserializeRegisterResponse(void); }; } // namespace Cynara diff --git a/src/common/protocol/ProtocolOpCode.h b/src/common/protocol/ProtocolOpCode.h index 2b4171c..7bd67ae 100644 --- a/src/common/protocol/ProtocolOpCode.h +++ b/src/common/protocol/ProtocolOpCode.h @@ -44,6 +44,14 @@ enum ProtocolOpCode : uint8_t { OpSetPolicies, OpCodeResponse, OpAdminCheckRequest, + + /** Opcodes 25 - 39 are reserved for future use */ + + /** Agent operations */ + OpAgentRegisterRequest = 40, + OpAgentRegisterResponse, + OpAgentActionRequest, + OpAgentActionResponse, }; } /* namespace Cynara */ -- 2.7.4 From c928edeb1753be9aed51016c44a171548b85421d Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Tue, 14 Oct 2014 09:39:46 +0200 Subject: [PATCH 02/16] Add AgentRegisterRequest handling Simple mockup of registering agent in cynara service. Change-Id: I8368c6ad1af946c86e44d196f073d1bf209e97c3 --- src/service/logic/Logic.cpp | 21 +++++++++++++++------ src/service/logic/Logic.h | 1 + 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index d4cc634..55f9f63 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -20,10 +20,11 @@ * @brief This file implements main class of logic layer in cynara service */ -#include +#include +#include -#include #include +#include #include #include #include @@ -32,11 +33,8 @@ #include #include #include - -#include - -#include
#include +#include #include #include #include @@ -44,12 +42,17 @@ #include #include #include +#include #include #include #include + +#include
#include #include +#include + #include "Logic.h" namespace Cynara { @@ -78,6 +81,12 @@ void Logic::execute(RequestContextPtr context, AdminCheckRequestPtr request) { request->sequenceNumber())); } +void Logic::execute(RequestContextPtr context, AgentRegisterRequestPtr request) { + // MOCKUP + context->returnResponse(context, std::make_shared( + AgentRegisterResponse::DONE, request->sequenceNumber())); +} + void Logic::execute(RequestContextPtr context, CancelRequestPtr request) { // MOCKUP context->returnResponse(context, std::make_shared(request->sequenceNumber())); diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index e74cffe..18d8abb 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -57,6 +57,7 @@ public: } virtual void execute(RequestContextPtr context, AdminCheckRequestPtr request); + virtual void execute(RequestContextPtr context, AgentRegisterRequestPtr request); virtual void execute(RequestContextPtr context, CancelRequestPtr request); virtual void execute(RequestContextPtr context, CheckRequestPtr request); virtual void execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request); -- 2.7.4 From fa2034d81afa540bf2a944289b44c97321c57719 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Fri, 24 Oct 2014 19:14:12 +0200 Subject: [PATCH 03/16] Set all needed socket descriptors to write state Now every socket that has data to write is set to write state after any event on any socket descriptor. Before only part of them were set. This change is needed to send requests to extension agents. Change-Id: Id0d9ed2e73f748bac27d1f5e3e1fd22a7a2bb816 --- src/service/sockets/SocketManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/service/sockets/SocketManager.cpp b/src/service/sockets/SocketManager.cpp index e454271..b7329b0 100644 --- a/src/service/sockets/SocketManager.cpp +++ b/src/service/sockets/SocketManager.cpp @@ -112,6 +112,9 @@ void SocketManager::mainLoop(void) { readyForWrite(i); --ret; } + } + + for (int i = 0; i < m_maxDesc + 1; ++i) { if (m_fds[i].isUsed() && m_fds[i].hasDataToWrite()) addWriteSocket(i); } -- 2.7.4 From 9ce6ffbb9656fd0682db12e9f94ad13465b6fe86 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Fri, 14 Nov 2014 18:58:37 +0100 Subject: [PATCH 04/16] Add LinkId type This type will be used to identify clients and agents. Change-Id: I6f6808919a6c8694ad8c3e51d826dc223541325f --- src/common/types/Link.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/common/types/Link.h diff --git a/src/common/types/Link.h b/src/common/types/Link.h new file mode 100644 index 0000000..d5a80a6 --- /dev/null +++ b/src/common/types/Link.h @@ -0,0 +1,34 @@ +/* + * 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/common/types/Link.h + * @author Adam Malinowski + * @version 1.0 + * @brief This file defines client connection related types + */ + +#ifndef SRC_COMMON_TYPES_LINK_H_ +#define SRC_COMMON_TYPES_LINK_H_ + +#include + +namespace Cynara { + +typedef BinaryQueuePtr LinkId; + +} // namespace Cynara + +#endif /* SRC_COMMON_TYPES_LINK_H_ */ -- 2.7.4 From 5a42ff8c0301cd13463e42860497912e504ce147 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Thu, 23 Oct 2014 10:13:55 +0200 Subject: [PATCH 05/16] Add AgentTalker class This class will be used as interface for plugin<->agent communication. Change-Id: Id6d6c439d531a8ff7e0b2b96005c12c5a5ab63b7 --- src/service/CMakeLists.txt | 1 + src/service/agent/AgentTalker.cpp | 52 ++++++++++++++++++++++++++++ src/service/agent/AgentTalker.h | 71 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 src/service/agent/AgentTalker.cpp create mode 100644 src/service/agent/AgentTalker.h diff --git a/src/service/CMakeLists.txt b/src/service/CMakeLists.txt index c317d8e..d6fd025 100644 --- a/src/service/CMakeLists.txt +++ b/src/service/CMakeLists.txt @@ -19,6 +19,7 @@ SET(CYNARA_SERVICE_PATH ${CYNARA_PATH}/service) SET(CYNARA_SOURCES + ${CYNARA_SERVICE_PATH}/agent/AgentTalker.cpp ${CYNARA_SERVICE_PATH}/logic/Logic.cpp ${CYNARA_SERVICE_PATH}/main/Cynara.cpp ${CYNARA_SERVICE_PATH}/main/main.cpp diff --git a/src/service/agent/AgentTalker.cpp b/src/service/agent/AgentTalker.cpp new file mode 100644 index 0000000..45f8a50 --- /dev/null +++ b/src/service/agent/AgentTalker.cpp @@ -0,0 +1,52 @@ +/* + * 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/service/agent/AgentTalker.cpp + * @author Adam Malinowski + * @version 1.0 + * @brief Definition of AgentTalker class + */ + +#include +#include +#include +#include +#include + +#include + +#include "AgentTalker.h" + +namespace Cynara { + +void AgentTalker::sendMessage(const AgentResponseType type, const RawBuffer &data) { + ResponseTakerPtr responseTaker = std::make_shared(); + auto context = std::make_shared(responseTaker, m_linkId); + context->returnResponse(context, + std::make_shared(type, data, m_checkId)); +} + +void AgentTalker::send(const PluginData &agentData) { + RawBuffer data(agentData.begin(), agentData.end()); + sendMessage(CYNARA_MSG_TYPE_ACTION, data); +} + +void AgentTalker::cancel(void) { + RawBuffer data; + sendMessage(CYNARA_MSG_TYPE_CANCEL, data); +} + +} // namespace Cynara diff --git a/src/service/agent/AgentTalker.h b/src/service/agent/AgentTalker.h new file mode 100644 index 0000000..fd45af1 --- /dev/null +++ b/src/service/agent/AgentTalker.h @@ -0,0 +1,71 @@ +/* + * 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/service/agent/AgentTalker.h + * @author Adam Malinowski + * @version 1.0 + * @brief Declaration of AgentTalker class + */ + +#ifndef SRC_SERVICE_AGENT_AGENTTALKER_H_ +#define SRC_SERVICE_AGENT_AGENTTALKER_H_ + +#include + +#include +#include +#include +#include + +#include + +namespace Cynara { + +class AgentTalker { +public: + AgentTalker(const AgentType &agentType, const LinkId &linkId, + const ProtocolFrameSequenceNumber checkId) : m_agentType(agentType), + m_checkId(checkId), m_linkId (linkId) {} + ~AgentTalker() {} + + void send(const PluginData &agentData); + void cancel(void); + + const AgentType &agentType(void) const { + return m_agentType; + } + + const LinkId linkId(void) const { + return m_linkId; + } + + ProtocolFrameSequenceNumber checkId(void) const { + return m_checkId; + } + +private: + const AgentType m_agentType; + const ProtocolFrameSequenceNumber m_checkId; + const LinkId m_linkId; + + void sendMessage(const AgentResponseType type, const RawBuffer &data); +}; + +typedef std::shared_ptr AgentTalkerPtr; + +} // namespace Cynara + +#endif /* SRC_SERVICE_AGENT_AGENTTALKER_H_ */ -- 2.7.4 From 96fc8d9bd0705063691fbe387b8e7ea5c0c0fa5c Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Fri, 24 Oct 2014 16:05:58 +0200 Subject: [PATCH 06/16] Add agent manager This commit introduces AgentManager class which will help plugins in communication with agents. Also registering and unregistering agents will be handled by this class. Change-Id: Id3f7e5785223c3b0316f97bc8107805572a0fd10 --- src/service/CMakeLists.txt | 1 + src/service/agent/AgentManager.cpp | 120 +++++++++++++++++++++++++++++++++++++ src/service/agent/AgentManager.h | 72 ++++++++++++++++++++++ src/service/logic/Logic.cpp | 5 +- src/service/logic/Logic.h | 6 ++ src/service/main/Cynara.cpp | 4 ++ src/service/main/Cynara.h | 1 + src/service/main/pointers.h | 3 + 8 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 src/service/agent/AgentManager.cpp create mode 100644 src/service/agent/AgentManager.h diff --git a/src/service/CMakeLists.txt b/src/service/CMakeLists.txt index d6fd025..675a866 100644 --- a/src/service/CMakeLists.txt +++ b/src/service/CMakeLists.txt @@ -19,6 +19,7 @@ SET(CYNARA_SERVICE_PATH ${CYNARA_PATH}/service) SET(CYNARA_SOURCES + ${CYNARA_SERVICE_PATH}/agent/AgentManager.cpp ${CYNARA_SERVICE_PATH}/agent/AgentTalker.cpp ${CYNARA_SERVICE_PATH}/logic/Logic.cpp ${CYNARA_SERVICE_PATH}/main/Cynara.cpp diff --git a/src/service/agent/AgentManager.cpp b/src/service/agent/AgentManager.cpp new file mode 100644 index 0000000..ee91e64 --- /dev/null +++ b/src/service/agent/AgentManager.cpp @@ -0,0 +1,120 @@ +/* + * 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/service/agent/AgentManager.cpp + * @author Adam Malinowski + * @version 1.0 + * @brief Definition of AgentManager class + */ + +#include + +#include +#include +#include + +#include "AgentManager.h" + +namespace Cynara { + +AgentRegisterResponse::Code AgentManager::registerAgent(const AgentType &agentType, + const LinkId &linkId) { + if (m_agents.find(agentType) != m_agents.end()) { + return AgentRegisterResponse::REJECTED; + } + + if (m_agents.insert(std::make_pair(agentType, linkId)).second) { + LOGI("Registered agent: <%s>", agentType.c_str()); + return AgentRegisterResponse::DONE; + } + + LOGE("Error in registering agent: <%s>", agentType.c_str()); + return AgentRegisterResponse::ERROR; +} + +bool AgentManager::getAgentType(const LinkId &linkId, AgentType &agentType) const { + for (const auto &x : m_agents) { + if (x.second == linkId) { + agentType = x.first; + return true; + } + } + return false; +} + +void AgentManager::unregisterAgent(const LinkId &linkId) { + AgentType agentType; + if (!getAgentType(linkId, agentType)) { + LOGD("Trying to unregister not registered agent"); + return; + } + m_agents.erase(agentType); + m_talkers.erase(linkId); + LOGI("Unregistered agent: <%s>", agentType.c_str()); +} + +AgentTalkerPtr AgentManager::createTalker(const AgentType &agentType) { + try { + ProtocolFrameSequenceNumber checkId = generateSequenceNumber(agentType); + const LinkId &linkId = m_agents.at(agentType); + + AgentTalkerPtr talker = std::make_shared(agentType, linkId, checkId); + if (m_talkers[linkId].insert(std::make_pair(checkId, talker)).second) { + LOGD("Created talker for: <%s>:[%" PRIu16 "]", agentType.c_str(), checkId); + return talker; + } + } catch (const std::out_of_range &) { + LOGE("Proper agent not found: <%s>", agentType.c_str()); + } + + return AgentTalkerPtr(); +} + +ProtocolFrameSequenceNumber AgentManager::generateSequenceNumber(const AgentType &agentType UNUSED) +{ + // TODO: implement smart sequence number generation, maybe unique per agent + return m_sequenceNumber++; +} + +AgentTalkerPtr AgentManager::getTalker(const LinkId &linkId, ProtocolFrameSequenceNumber requestId) + const { + const auto talkerMap = m_talkers.find(linkId); + if (talkerMap == m_talkers.end()) { + return AgentTalkerPtr(); + } + + const auto talker = talkerMap->second.find(requestId); + return talker != talkerMap->second.end() ? talker->second : AgentTalkerPtr(); +} + +void AgentManager::removeTalker(const AgentTalkerPtr &agentTalker) { + m_talkers[agentTalker->linkId()].erase(agentTalker->checkId()); +} + +void AgentManager::cleanupAgent(const LinkId &linkId, TalkerCleanupFunction cleanupFunction) { + auto talkerMap = m_talkers.find(linkId); + if (talkerMap == m_talkers.end()) + return; + + if (cleanupFunction) { + for (auto p : talkerMap->second) { + cleanupFunction(p.second); + } + } + unregisterAgent(linkId); +} + +} // namespace Cynara diff --git a/src/service/agent/AgentManager.h b/src/service/agent/AgentManager.h new file mode 100644 index 0000000..38dca72 --- /dev/null +++ b/src/service/agent/AgentManager.h @@ -0,0 +1,72 @@ +/* + * 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/service/agent/AgentManager.h + * @author Adam Malinowski + * @version 1.0 + * @brief Declaration of AgentManager class + */ + +#ifndef SRC_SERVICE_AGENT_AGENTMANAGER_H_ +#define SRC_SERVICE_AGENT_AGENTMANAGER_H_ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +namespace Cynara { + +class AgentManager { +public: + typedef std::map Talkers; + typedef std::function TalkerCleanupFunction; + + AgentManager() : m_sequenceNumber(0) {} + ~AgentManager() {} + + typedef enum { + RR_DONE, + RR_REJECTED, + RR_ERROR + } RegisterResult; + + AgentRegisterResponse::Code registerAgent(const AgentType &agentType, const LinkId &linkId); + + AgentTalkerPtr createTalker(const AgentType &agentType); + void removeTalker(const AgentTalkerPtr &agentTalkerPtr); + AgentTalkerPtr getTalker(const LinkId &linkId, ProtocolFrameSequenceNumber requestId) const; + void cleanupAgent(const LinkId &linkId, TalkerCleanupFunction cleanupFunction); + +private: + std::map m_agents; + std::map m_talkers; + ProtocolFrameSequenceNumber m_sequenceNumber; + + ProtocolFrameSequenceNumber generateSequenceNumber(const AgentType &agentType); + bool getAgentType(const LinkId &linkId, AgentType &agentType) const; + void unregisterAgent(const LinkId &linkId); +}; + +} // namespace Cynara + +#endif /* SRC_SERVICE_AGENT_AGENTMANAGER_H_ */ diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index 55f9f63..7227ef9 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -48,6 +48,7 @@ #include #include
+#include #include #include @@ -82,9 +83,9 @@ void Logic::execute(RequestContextPtr context, AdminCheckRequestPtr request) { } void Logic::execute(RequestContextPtr context, AgentRegisterRequestPtr request) { - // MOCKUP + auto result = m_agentManager->registerAgent(request->agentType(), context->responseQueue()); context->returnResponse(context, std::make_shared( - AgentRegisterResponse::DONE, request->sequenceNumber())); + result, request->sequenceNumber())); } void Logic::execute(RequestContextPtr context, CancelRequestPtr request) { diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index 18d8abb..fdf338e 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -38,6 +38,10 @@ public: Logic(); virtual ~Logic(); + void bindAgentManager(const AgentManagerPtr &agentManager) { + m_agentManager = agentManager; + } + void bindPluginManager(PluginManagerPtr pluginManager) { m_pluginManager = pluginManager; } @@ -51,6 +55,7 @@ public: } void unbindAll(void) { + m_agentManager.reset(); m_pluginManager.reset(); m_storage.reset(); m_socketManager.reset(); @@ -68,6 +73,7 @@ public: virtual void contextClosed(RequestContextPtr context); private: + AgentManagerPtr m_agentManager; PluginManagerPtr m_pluginManager; StoragePtr m_storage; SocketManagerPtr m_socketManager; diff --git a/src/service/main/Cynara.cpp b/src/service/main/Cynara.cpp index c0f77ef..96443ce 100644 --- a/src/service/main/Cynara.cpp +++ b/src/service/main/Cynara.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -47,12 +48,14 @@ Cynara::~Cynara() { } void Cynara::init(void) { + m_agentManager = std::make_shared(); m_logic = std::make_shared(); m_pluginManager = std::make_shared(PathConfig::PluginPath::serviceDir); m_socketManager = std::make_shared(); m_storageBackend = std::make_shared(PathConfig::StoragePath::dbDir); m_storage = std::make_shared(*m_storageBackend); + m_logic->bindAgentManager(m_agentManager); m_logic->bindPluginManager(m_pluginManager); m_logic->bindStorage(m_storage); m_logic->bindSocketManager(m_socketManager); @@ -79,6 +82,7 @@ void Cynara::finalize(void) { m_socketManager->unbindAll(); } + m_agentManager.reset(); m_logic.reset(); m_pluginManager.reset(); m_socketManager.reset(); diff --git a/src/service/main/Cynara.h b/src/service/main/Cynara.h index 2eb94dc..89bdd76 100644 --- a/src/service/main/Cynara.h +++ b/src/service/main/Cynara.h @@ -37,6 +37,7 @@ public: void finalize(void); private: + AgentManagerPtr m_agentManager; LogicPtr m_logic; PluginManagerPtr m_pluginManager; SocketManagerPtr m_socketManager; diff --git a/src/service/main/pointers.h b/src/service/main/pointers.h index e31eeb8..f32c4ab 100644 --- a/src/service/main/pointers.h +++ b/src/service/main/pointers.h @@ -27,6 +27,9 @@ namespace Cynara { +class AgentManager; +typedef std::shared_ptr AgentManagerPtr; + class Logic; typedef std::shared_ptr LogicPtr; -- 2.7.4 From e67f20e8674202893ccfa0f7332acd6a567c404a Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 3 Nov 2014 11:16:22 +0100 Subject: [PATCH 07/16] Add CheckContext class This class will be used for storing all data related to check request. This data will be used to send response to client when answer is ready. Change-Id: I20b665409e15d249a9c55615a39f4ab5b361bc18 --- src/service/request/CheckContext.h | 68 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/service/request/CheckContext.h diff --git a/src/service/request/CheckContext.h b/src/service/request/CheckContext.h new file mode 100644 index 0000000..5184296 --- /dev/null +++ b/src/service/request/CheckContext.h @@ -0,0 +1,68 @@ +/* + * 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/service/request/CheckContext.h + * @author Adam Malinowski + * @version 1.0 + * @brief Declaration of CheckContext class + */ + +#ifndef SRC_SERVICE_REQUEST_CHECKCONTEXT_H_ +#define SRC_SERVICE_REQUEST_CHECKCONTEXT_H_ + +#include + +#include +#include +#include +#include + +#include + +#include + +namespace Cynara { + +class CheckContext { +public: + CheckContext(const PolicyKey &key, RequestContextPtr requestContext, + ProtocolFrameSequenceNumber checkId, ServicePluginInterfacePtr plugin, + const AgentTalkerPtr &agentTalkerPtr) : m_agentTalker(agentTalkerPtr), + m_checkId(checkId), m_key(key), m_plugin(plugin), + m_requestContext(requestContext), m_cancelled(false) {} + ~CheckContext() {} + + AgentTalkerPtr m_agentTalker; + const ProtocolFrameSequenceNumber m_checkId; + const PolicyKey m_key; + ServicePluginInterfacePtr m_plugin; + RequestContextPtr m_requestContext; + bool m_cancelled; + + void cancel(void) { + m_cancelled = true; + } + + bool cancelled(void) const { + return m_cancelled; + } +}; + +typedef std::shared_ptr CheckContextPtr; + +} // namespace Cynara + +#endif /* SRC_SERVICE_REQUEST_CHECKCONTEXT_H_ */ -- 2.7.4 From fabe257134bcd544deeb68de52ca6ed0eb0a0da4 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 3 Nov 2014 11:21:25 +0100 Subject: [PATCH 08/16] Add manager for check contexts This class will be used by service logic to create and handle check contexts. Change-Id: I8c1f1265336dd8b5a428ed254083d1e508579a2e --- src/service/CMakeLists.txt | 1 + src/service/logic/Logic.h | 2 + src/service/request/CheckRequestManager.cpp | 91 +++++++++++++++++++++++++++++ src/service/request/CheckRequestManager.h | 61 +++++++++++++++++++ 4 files changed, 155 insertions(+) create mode 100644 src/service/request/CheckRequestManager.cpp create mode 100644 src/service/request/CheckRequestManager.h diff --git a/src/service/CMakeLists.txt b/src/service/CMakeLists.txt index 675a866..d4dd32e 100644 --- a/src/service/CMakeLists.txt +++ b/src/service/CMakeLists.txt @@ -24,6 +24,7 @@ SET(CYNARA_SOURCES ${CYNARA_SERVICE_PATH}/logic/Logic.cpp ${CYNARA_SERVICE_PATH}/main/Cynara.cpp ${CYNARA_SERVICE_PATH}/main/main.cpp + ${CYNARA_SERVICE_PATH}/request/CheckRequestManager.cpp ${CYNARA_SERVICE_PATH}/sockets/Descriptor.cpp ${CYNARA_SERVICE_PATH}/sockets/SocketManager.cpp ) diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index fdf338e..35226d7 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -28,6 +28,7 @@ #include
#include +#include #include #include @@ -74,6 +75,7 @@ public: private: AgentManagerPtr m_agentManager; + CheckRequestManager m_checkRequestManager; PluginManagerPtr m_pluginManager; StoragePtr m_storage; SocketManagerPtr m_socketManager; diff --git a/src/service/request/CheckRequestManager.cpp b/src/service/request/CheckRequestManager.cpp new file mode 100644 index 0000000..8090f47 --- /dev/null +++ b/src/service/request/CheckRequestManager.cpp @@ -0,0 +1,91 @@ +/* + * 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/service/request/CheckRequestManager.cpp + * @author Adam Malinowski + * @version 1.0 + * @brief Definition of CheckRequestManager class + */ + +#include + +#include +#include +#include + +#include "CheckRequestManager.h" + +namespace Cynara { + +CheckContextPtr CheckRequestManager::createContext(const PolicyKey &key, + const RequestContextPtr &request, + ProtocolFrameSequenceNumber checkId, + const ServicePluginInterfacePtr &plugin, + const AgentTalkerPtr &agentTalkerPtr) { + + CheckContextPtr checkPtr = std::make_shared(key, request, checkId, plugin, + agentTalkerPtr); + if (m_checks[request->responseQueue()].insert(std::make_pair(checkId, checkPtr)).second) { + return checkPtr; + } + + return CheckContextPtr(); +} + +CheckContextPtr CheckRequestManager::getContext(const LinkId &linkId, + ProtocolFrameSequenceNumber checkId) { + const auto checkMap = m_checks.find(linkId); + if (checkMap == m_checks.end()) { + return CheckContextPtr(); + } + + const auto checkContext = checkMap->second.find(checkId); + return checkContext != checkMap->second.end() ? checkContext->second : CheckContextPtr(); +} + +CheckContextPtr CheckRequestManager::getContext(const AgentTalkerPtr &talker) { + for (const auto &checkMap : m_checks) { + for (const auto &check : checkMap.second) { + if (check.second->m_agentTalker == talker) { + return check.second; + } + } + } + return nullptr; +} + +void CheckRequestManager::removeRequest(const CheckContextPtr &checkContextPtr) { + m_checks[checkContextPtr->m_requestContext->responseQueue()].erase(checkContextPtr->m_checkId); + auto it = m_checks.find(checkContextPtr->m_requestContext->responseQueue()); + if (it->second.empty()) { + m_checks.erase(it); + } +} + +void CheckRequestManager::cancelRequests(const LinkId &linkId, CancelRequestFunction cancelFunction) +{ + auto checkMap = m_checks.find(linkId); + if (checkMap == m_checks.end()) + return; + + if (cancelFunction) { + for (auto p : checkMap->second) { + cancelFunction(p.second); + } + } +} + +} // namespace Cynara diff --git a/src/service/request/CheckRequestManager.h b/src/service/request/CheckRequestManager.h new file mode 100644 index 0000000..f71f8f1 --- /dev/null +++ b/src/service/request/CheckRequestManager.h @@ -0,0 +1,61 @@ +/* + * 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/service/request/CheckRequestManager.h + * @author Adam Malinowski + * @version 1.0 + * @brief Declaration of CheckRequestManager class + */ + +#ifndef SRC_SERVICE_AGENT_CHECKREQUESTMANAGER_H_ +#define SRC_SERVICE_AGENT_CHECKREQUESTMANAGER_H_ + +#include +#include + +#include +#include +#include + +#include + +namespace Cynara { + +class CheckRequestManager { +public: + typedef std::map CheckContexts; + typedef std::function CancelRequestFunction; + + CheckRequestManager() {} + ~CheckRequestManager() {} + + CheckContextPtr createContext(const PolicyKey &key, const RequestContextPtr &request, + ProtocolFrameSequenceNumber checkId, + const ServicePluginInterfacePtr &plugin, + const AgentTalkerPtr &agentTalkerPtr); + void removeRequest(const CheckContextPtr &checkContextPtr); + + CheckContextPtr getContext(const LinkId &linkId, ProtocolFrameSequenceNumber checkId); + CheckContextPtr getContext(const AgentTalkerPtr &talker); + void cancelRequests(const LinkId &linkId, CancelRequestFunction cancelFunction); + +private: + std::map m_checks; +}; + +} // namespace Cynara + +#endif /* SRC_SERVICE_AGENT_CHECKREQUESTMANAGER_H_ */ -- 2.7.4 From 95108c995a7705cbb89769cd6f0beb6fa8545741 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 3 Nov 2014 14:45:03 +0100 Subject: [PATCH 09/16] Handle check request with agent usage This patch introduces sending request to agent and storing context for future. Change-Id: I8187b4c5e66daa155b485b5ff6b9710de27f6345 --- src/service/agent/AgentManager.cpp | 2 +- src/service/logic/Logic.cpp | 50 ++++++++++++++++++++++++++++++++------ src/service/logic/Logic.h | 6 +++-- 3 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/service/agent/AgentManager.cpp b/src/service/agent/AgentManager.cpp index ee91e64..d551790 100644 --- a/src/service/agent/AgentManager.cpp +++ b/src/service/agent/AgentManager.cpp @@ -77,7 +77,7 @@ AgentTalkerPtr AgentManager::createTalker(const AgentType &agentType) { return talker; } } catch (const std::out_of_range &) { - LOGE("Proper agent not found: <%s>", agentType.c_str()); + LOGE("Required agent is not registered: <%s>", agentType.c_str()); } return AgentTalkerPtr(); diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index 7227ef9..dfb968a 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -21,8 +21,11 @@ */ #include +#include +#include #include +#include #include #include #include @@ -95,14 +98,20 @@ void Logic::execute(RequestContextPtr context, CancelRequestPtr request) { void Logic::execute(RequestContextPtr context, CheckRequestPtr request) { PolicyResult result(PredefinedPolicyType::DENY); - if (check(context, request->key(), result)) { + if (check(context, request->key(), request->sequenceNumber(), result)) { context->returnResponse(context, std::make_shared(result, request->sequenceNumber())); } } -bool Logic::check(RequestContextPtr context UNUSED, const PolicyKey &key, - PolicyResult& result) { +bool Logic::check(const RequestContextPtr &context, const PolicyKey &key, + ProtocolFrameSequenceNumber checkId, PolicyResult &result) { + + if (m_checkRequestManager.getContext(context->responseQueue(), checkId)) { + LOGE("Check request for checkId: [%" PRIu16 "] is already processing", checkId); + return false; + } + result = m_storage->checkPolicy(key); switch (result.policyType()) { @@ -114,9 +123,19 @@ bool Logic::check(RequestContextPtr context UNUSED, const PolicyKey &key, return true; } + return pluginCheck(context, key, checkId, result); +} + +bool Logic::pluginCheck(const RequestContextPtr &context, const PolicyKey &key, + ProtocolFrameSequenceNumber checkId, PolicyResult &result) { + + LOGD("Trying to check policy: <%s> in plugin.", key.toString().c_str()); + ExternalPluginPtr plugin = m_pluginManager->getPlugin(result.policyType()); if (!plugin) { - throw PluginNotFoundException(result); + LOGE("Plugin not found for policy: [0x%x]", result.policyType()); + result = PolicyResult(PredefinedPolicyType::DENY); + return true; } ServicePluginInterfacePtr servicePlugin = @@ -134,12 +153,27 @@ bool Logic::check(RequestContextPtr context UNUSED, const PolicyKey &key, switch (ret) { case ServicePluginInterface::PluginStatus::ANSWER_READY: return true; - case ServicePluginInterface::PluginStatus::ANSWER_NOTREADY: - //todo send request to agent - //context should be saved in plugin in order to return answer when ready + case ServicePluginInterface::PluginStatus::ANSWER_NOTREADY: { + result = PolicyResult(PredefinedPolicyType::DENY); + AgentTalkerPtr agentTalker = m_agentManager->createTalker(requiredAgent); + if (!agentTalker) { + LOGE("Required agent talker for: <%s> could not be created.", + requiredAgent.c_str()); + return true; + } + + if (!m_checkRequestManager.createContext(key, context, checkId, servicePlugin, + agentTalker)) { + LOGE("Check context for checkId: [%" PRIu16 "] could not be created.", + checkId); + m_agentManager->removeTalker(agentTalker); + return true; + } + agentTalker->send(pluginData); + } return false; default: - throw PluginErrorException(key); + throw PluginErrorException(key); // This 'throw' should be removed or handled properly. } } diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index 35226d7..a90c08c 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -80,8 +80,10 @@ private: StoragePtr m_storage; SocketManagerPtr m_socketManager; - bool check(RequestContextPtr context, const PolicyKey &key, PolicyResult& result); - + bool check(const RequestContextPtr &context, const PolicyKey &key, + ProtocolFrameSequenceNumber checkId, PolicyResult &result); + bool pluginCheck(const RequestContextPtr &context, const PolicyKey &key, + ProtocolFrameSequenceNumber checkId, PolicyResult &result); void onPoliciesChanged(void); }; -- 2.7.4 From 3fbc0c58ea63228686da510af345d3d893d4f8db Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 3 Nov 2014 14:49:59 +0100 Subject: [PATCH 10/16] Handle cancel request This patch implements handling cancel request from client. Change-Id: I2b5537ef8b481f3a3160702d0a549945b8a11622 --- src/service/logic/Logic.cpp | 16 +++++++++++++++- src/service/logic/Logic.h | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index dfb968a..037deb8 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -92,7 +92,21 @@ void Logic::execute(RequestContextPtr context, AgentRegisterRequestPtr request) } void Logic::execute(RequestContextPtr context, CancelRequestPtr request) { - // MOCKUP + CheckContextPtr checkContextPtr = m_checkRequestManager.getContext(context->responseQueue(), + request->sequenceNumber()); + if (!checkContextPtr) { + LOGD("Cancel request id: [%" PRIu16 "] with no matching request in progress.", + request->sequenceNumber()); + return; + } + + if (checkContextPtr->cancelled()) + return; + + checkContextPtr->cancel(); + checkContextPtr->m_agentTalker->cancel(); + + LOGD("Returning response for cancel request id: [%" PRIu16 "].", request->sequenceNumber()); context->returnResponse(context, std::make_shared(request->sequenceNumber())); } diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index a90c08c..dbbc7d6 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -84,6 +84,7 @@ private: ProtocolFrameSequenceNumber checkId, PolicyResult &result); bool pluginCheck(const RequestContextPtr &context, const PolicyKey &key, ProtocolFrameSequenceNumber checkId, PolicyResult &result); + void onPoliciesChanged(void); }; -- 2.7.4 From 794cffc86808db86cf059214b9edb8c03e1e93d0 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 3 Nov 2014 14:53:33 +0100 Subject: [PATCH 11/16] Handle agent response This patch handles response from agent of both types: action and cancel. Change-Id: I3168f4f7466c79bdcb9a3f6b1c3d6863ddcf952c --- src/service/logic/Logic.cpp | 67 +++++++++++++++++++++++++++++++++++++++++++++ src/service/logic/Logic.h | 6 ++++ 2 files changed, 73 insertions(+) diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index 037deb8..4cf78eb 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +58,8 @@ #include +#include + #include "Logic.h" namespace Cynara { @@ -85,6 +88,40 @@ void Logic::execute(RequestContextPtr context, AdminCheckRequestPtr request) { request->sequenceNumber())); } +void Logic::execute(RequestContextPtr context, AgentActionRequestPtr request) { + AgentTalkerPtr talkerPtr = m_agentManager->getTalker(context->responseQueue(), + request->sequenceNumber()); + if (!talkerPtr) { + LOGD("Received response from agent with invalid request id: [%" PRIu16 "]", + request->sequenceNumber()); + return; + } + + CheckContextPtr checkContextPtr = m_checkRequestManager.getContext(talkerPtr); + if (!checkContextPtr) { + LOGE("No matching check context for agent talker."); + m_agentManager->removeTalker(talkerPtr); + return; + } + + if (!checkContextPtr->cancelled()) { + PluginData data(request->data().begin(), request->data().end()); + if (request->type() == CYNARA_MSG_TYPE_CANCEL) { + // Nothing to do for now + } else if (request->type() == CYNARA_MSG_TYPE_ACTION) { + update(checkContextPtr->m_key, checkContextPtr->m_checkId, data, + checkContextPtr->m_requestContext, checkContextPtr->m_plugin); + } else { + LOGE("Invalid response type [%d] in response from agent <%s>", + static_cast(request->type()), talkerPtr->agentType().c_str()); + // TODO: disconnect agent + } + } + + m_agentManager->removeTalker(talkerPtr); + m_checkRequestManager.removeRequest(checkContextPtr); +} + void Logic::execute(RequestContextPtr context, AgentRegisterRequestPtr request) { auto result = m_agentManager->registerAgent(request->agentType(), context->responseQueue()); context->returnResponse(context, std::make_shared( @@ -191,6 +228,36 @@ bool Logic::pluginCheck(const RequestContextPtr &context, const PolicyKey &key, } } +bool Logic::update(const PolicyKey &key, ProtocolFrameSequenceNumber checkId, + const PluginData &agentData, const RequestContextPtr &context, + const ServicePluginInterfacePtr &plugin) { + + LOGD("Check update: <%s>:[%" PRIu16 "]", key.toString().c_str(), checkId); + + PolicyResult result; + bool answerReady = false; + auto ret = plugin->update(key.client().toString(), key.user().toString(), + key.privilege().toString(), agentData, result); + switch (ret) { + case ServicePluginInterface::PluginStatus::SUCCESS: + answerReady = true; + break; + case ServicePluginInterface::PluginStatus::ERROR: + result = PolicyResult(PredefinedPolicyType::DENY); + answerReady = true; + break; + default: + throw PluginErrorException(key); + } + + if (answerReady && context->responseQueue()) { + context->returnResponse(context, std::make_shared(result, checkId)); + return true; + } + + return false; +} + void Logic::execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request) { auto code = CodeResponse::Code::OK; diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index dbbc7d6..57a862c 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -32,6 +32,8 @@ #include #include +#include + namespace Cynara { class Logic : public RequestTaker { @@ -63,6 +65,7 @@ public: } virtual void execute(RequestContextPtr context, AdminCheckRequestPtr request); + virtual void execute(RequestContextPtr context, AgentActionRequestPtr request); virtual void execute(RequestContextPtr context, AgentRegisterRequestPtr request); virtual void execute(RequestContextPtr context, CancelRequestPtr request); virtual void execute(RequestContextPtr context, CheckRequestPtr request); @@ -84,6 +87,9 @@ private: ProtocolFrameSequenceNumber checkId, PolicyResult &result); bool pluginCheck(const RequestContextPtr &context, const PolicyKey &key, ProtocolFrameSequenceNumber checkId, PolicyResult &result); + bool update(const PolicyKey &key, ProtocolFrameSequenceNumber checkId, + const PluginData &agentData, const RequestContextPtr &request, + const ServicePluginInterfacePtr &plugin); void onPoliciesChanged(void); }; -- 2.7.4 From ced9c53a12b1f47eb2087b97650c0085fdb65c9e Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 3 Nov 2014 14:57:13 +0100 Subject: [PATCH 12/16] Handle client and agent disconnection This patch handles situations where client and/or agent connection to cynara service is closed. Change-Id: I410b6da96102b6ae16442e90dbbb1e867490287a --- src/service/logic/Logic.cpp | 39 +++++++++++++++++++++++++++++++++++++-- src/service/logic/Logic.h | 3 +++ 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/service/logic/Logic.cpp b/src/service/logic/Logic.cpp index 4cf78eb..8f51af5 100644 --- a/src/service/logic/Logic.cpp +++ b/src/service/logic/Logic.cpp @@ -63,6 +63,7 @@ #include "Logic.h" namespace Cynara { + Logic::Logic() { } @@ -307,8 +308,17 @@ void Logic::execute(RequestContextPtr context, SetPoliciesRequestPtr request) { request->sequenceNumber())); } -void Logic::contextClosed(RequestContextPtr context UNUSED) { - //We don't care now, but we will +void Logic::contextClosed(RequestContextPtr context) { + LOGD("context closed"); + + LinkId linkId = context->responseQueue(); + + m_agentManager->cleanupAgent(linkId, [&](const AgentTalkerPtr &talker) -> void { + handleAgentTalkerDisconnection(talker); }); + + m_checkRequestManager.cancelRequests(linkId, + [&](const CheckContextPtr &checkContextPtr) -> void { + handleClientDisconnection(checkContextPtr); }); } void Logic::onPoliciesChanged(void) { @@ -317,4 +327,29 @@ void Logic::onPoliciesChanged(void) { //todo remove all saved contexts (if there will be any saved contexts) } +void Logic::handleAgentTalkerDisconnection(const AgentTalkerPtr &agentTalkerPtr) { + CheckContextPtr checkContextPtr = m_checkRequestManager.getContext(agentTalkerPtr); + if (checkContextPtr == nullptr) { + LOGE("No matching check context for agent talker."); + return; + } + + if (!checkContextPtr->cancelled() && checkContextPtr->m_requestContext->responseQueue()) { + PolicyResult result(PredefinedPolicyType::DENY); + checkContextPtr->m_requestContext->returnResponse(checkContextPtr->m_requestContext, + std::make_shared(result, checkContextPtr->m_checkId)); + } + + m_checkRequestManager.removeRequest(checkContextPtr); +} + +void Logic::handleClientDisconnection(const CheckContextPtr &checkContextPtr) { + LOGD("Handle client disconnection"); + + if (!checkContextPtr->cancelled()) { + checkContextPtr->cancel(); + checkContextPtr->m_agentTalker->cancel(); + } +} + } // namespace Cynara diff --git a/src/service/logic/Logic.h b/src/service/logic/Logic.h index 57a862c..33c5701 100644 --- a/src/service/logic/Logic.h +++ b/src/service/logic/Logic.h @@ -91,6 +91,9 @@ private: const PluginData &agentData, const RequestContextPtr &request, const ServicePluginInterfacePtr &plugin); + void handleAgentTalkerDisconnection(const AgentTalkerPtr &agentTalkerPtr); + void handleClientDisconnection(const CheckContextPtr &checkContextPtr); + void onPoliciesChanged(void); }; -- 2.7.4 From f4e6749ef8d1fdd86946c848bb2d90431ca7e6ad Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Sat, 15 Nov 2014 05:39:18 +0100 Subject: [PATCH 13/16] Release 0.4.0 Change-Id: Ia8f5a7e623bcbce58f9574c084a6472ea59e271a --- CMakeLists.txt | 2 +- changelog | 28 ++++++++++++++++++++++++++++ packaging/cynara.spec | 2 +- src/admin/CMakeLists.txt | 2 +- src/client-common/CMakeLists.txt | 2 +- src/client/CMakeLists.txt | 2 +- src/common/CMakeLists.txt | 2 +- src/helpers/creds-commons/CMakeLists.txt | 2 +- src/helpers/creds-dbus/CMakeLists.txt | 2 +- src/helpers/creds-socket/CMakeLists.txt | 2 +- src/helpers/session/CMakeLists.txt | 2 +- 11 files changed, 38 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dc951bb..5271bb2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3) PROJECT("cynara") -set(CYNARA_VERSION 0.2.2) +set(CYNARA_VERSION 0.4.0) ############################# cmake packages ################################## diff --git a/changelog b/changelog index a2d08e3..e841be7 100644 --- a/changelog +++ b/changelog @@ -1,5 +1,33 @@ ############################## +Release: 0.4.0 +Date: 2014.11.15 +Name: Asynchronous client and extensions API + +Libraries: +libcynara-admin.0.4.0 +libcynara-agent.0.4.0 +libcynara-client-async.0.4.0 +libcynara-client-commmons.0.4.0 +libcynara-client.0.4.0 +libcynara-commons.0.4.0 +libcynara-creds-commons.0.4.0 +libcynara-creds-dbus.0.4.0 +libcynara-creds-socket.0.4.0 +libcynara-session.0.4.0 +libcynara-storage.0.4.0 + +Description: +Asynchronous client library. +Admin API: admin_check, NONE policies +Common error codes +Extensions: plugins and agents API +Database integrity +Migration package +Common client exceptions handling + +############################## + Release: 0.3.0 Date: 2014.09.05 Name: Helper libraries diff --git a/packaging/cynara.spec b/packaging/cynara.spec index 88e9209..ae98c80 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -1,6 +1,6 @@ Name: cynara Summary: Cynara service with client libraries -Version: 0.3.0 +Version: 0.4.0 Release: 1 Group: Security/Application Privilege License: Apache-2.0 diff --git a/src/admin/CMakeLists.txt b/src/admin/CMakeLists.txt index 4918571..7cab9f6 100644 --- a/src/admin/CMakeLists.txt +++ b/src/admin/CMakeLists.txt @@ -17,7 +17,7 @@ # SET(LIB_CYNARA_ADMIN_VERSION_MAJOR 0) -SET(LIB_CYNARA_ADMIN_VERSION ${LIB_CYNARA_ADMIN_VERSION_MAJOR}.3.0) +SET(LIB_CYNARA_ADMIN_VERSION ${LIB_CYNARA_ADMIN_VERSION_MAJOR}.4.0) SET(CYNARA_LIB_CYNARA_ADMIN_PATH ${CYNARA_PATH}/admin) diff --git a/src/client-common/CMakeLists.txt b/src/client-common/CMakeLists.txt index 5436884..36c6806 100644 --- a/src/client-common/CMakeLists.txt +++ b/src/client-common/CMakeLists.txt @@ -17,7 +17,7 @@ # SET(LIB_CYNARA_CLIENT_COMMON_VERSION_MAJOR 0) -SET(LIB_CYNARA_CLIENT_COMMON_VERSION ${LIB_CYNARA_CLIENT_COMMON_VERSION_MAJOR}.3.0) +SET(LIB_CYNARA_CLIENT_COMMON_VERSION ${LIB_CYNARA_CLIENT_COMMON_VERSION_MAJOR}.4.0) SET(LIB_CYNARA_COMMON_PATH ${CYNARA_PATH}/client-common) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index db0622c..79d85a2 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -18,7 +18,7 @@ # SET(LIB_CYNARA_VERSION_MAJOR 0) -SET(LIB_CYNARA_VERSION ${LIB_CYNARA_VERSION_MAJOR}.3.0) +SET(LIB_CYNARA_VERSION ${LIB_CYNARA_VERSION_MAJOR}.4.0) SET(LIB_CYNARA_PATH ${CYNARA_PATH}/client) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 7f3da76..8cf615c 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -17,7 +17,7 @@ # SET(CYNARA_COMMON_VERSION_MAJOR 0) -SET(CYNARA_COMMON_VERSION ${CYNARA_COMMON_VERSION_MAJOR}.3.0) +SET(CYNARA_COMMON_VERSION ${CYNARA_COMMON_VERSION_MAJOR}.4.0) SET(COMMON_PATH ${CYNARA_PATH}/common) diff --git a/src/helpers/creds-commons/CMakeLists.txt b/src/helpers/creds-commons/CMakeLists.txt index 5dd5007..bafa025 100644 --- a/src/helpers/creds-commons/CMakeLists.txt +++ b/src/helpers/creds-commons/CMakeLists.txt @@ -19,7 +19,7 @@ # SET(LIB_CREDS_COMMONS_VERSION_MAJOR 0) -SET(LIB_CREDS_COMMONS_VERSION ${LIB_CREDS_COMMONS_VERSION_MAJOR}.3.0) +SET(LIB_CREDS_COMMONS_VERSION ${LIB_CREDS_COMMONS_VERSION_MAJOR}.4.0) SET(LIB_CREDS_COMMONS_PATH ${CYNARA_PATH}/helpers/creds-commons) diff --git a/src/helpers/creds-dbus/CMakeLists.txt b/src/helpers/creds-dbus/CMakeLists.txt index bc1d95c..69b94e2 100644 --- a/src/helpers/creds-dbus/CMakeLists.txt +++ b/src/helpers/creds-dbus/CMakeLists.txt @@ -19,7 +19,7 @@ # SET(LIB_CREDS_DBUS_VERSION_MAJOR 0) -SET(LIB_CREDS_DBUS_VERSION ${LIB_CREDS_DBUS_VERSION_MAJOR}.3.0) +SET(LIB_CREDS_DBUS_VERSION ${LIB_CREDS_DBUS_VERSION_MAJOR}.4.0) SET(LIB_CREDS_DBUS_PATH ${CYNARA_PATH}/helpers/creds-dbus) diff --git a/src/helpers/creds-socket/CMakeLists.txt b/src/helpers/creds-socket/CMakeLists.txt index 1c8d301..1d40f3b 100644 --- a/src/helpers/creds-socket/CMakeLists.txt +++ b/src/helpers/creds-socket/CMakeLists.txt @@ -19,7 +19,7 @@ # SET(LIB_CREDS_SOCKET_VERSION_MAJOR 0) -SET(LIB_CREDS_SOCKET_VERSION ${LIB_CREDS_SOCKET_VERSION_MAJOR}.3.0) +SET(LIB_CREDS_SOCKET_VERSION ${LIB_CREDS_SOCKET_VERSION_MAJOR}.4.0) SET(LIB_CREDS_SOCKET_PATH ${CYNARA_PATH}/helpers/creds-socket) diff --git a/src/helpers/session/CMakeLists.txt b/src/helpers/session/CMakeLists.txt index 00c5d3d..6ad7234 100644 --- a/src/helpers/session/CMakeLists.txt +++ b/src/helpers/session/CMakeLists.txt @@ -19,7 +19,7 @@ # SET(LIB_SESSION_VERSION_MAJOR 0) -SET(LIB_SESSION_VERSION ${LIB_SESSION_VERSION_MAJOR}.3.0) +SET(LIB_SESSION_VERSION ${LIB_SESSION_VERSION_MAJOR}.4.0) SET(LIB_SESSION_PATH ${CYNARA_PATH}/helpers/session) -- 2.7.4 From 88b6ae7330c1f3d015b1d2584cd7fe678a0e5c72 Mon Sep 17 00:00:00 2001 From: Adam Malinowski Date: Mon, 17 Nov 2014 08:50:27 +0100 Subject: [PATCH 14/16] Fix linking dependencies PluginManager was moved from service to common but linking with 'dl' library stayed in service. This patch moves linking with dl to common. Change-Id: If1be63e86dfe4c8651b48bbe9facc80160fd9f32 --- src/common/CMakeLists.txt | 1 + src/service/CMakeLists.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 8cf615c..bd3911f 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -89,6 +89,7 @@ ENDIF (CMAKE_BUILD_TYPE MATCHES "DEBUG") TARGET_LINK_LIBRARIES(${TARGET_CYNARA_COMMON} ${CYNARA_DEP_LIBRARIES} ${CYNARA_DBG_LIBRARIES} + dl ) INSTALL(TARGETS ${TARGET_CYNARA_COMMON} DESTINATION ${LIB_INSTALL_DIR}) diff --git a/src/service/CMakeLists.txt b/src/service/CMakeLists.txt index d4dd32e..b28058b 100644 --- a/src/service/CMakeLists.txt +++ b/src/service/CMakeLists.txt @@ -41,7 +41,6 @@ TARGET_LINK_LIBRARIES(${TARGET_CYNARA} ${CYNARA_DEP_LIBRARIES} ${TARGET_CYNARA_COMMON} ${TARGET_LIB_CYNARA_STORAGE} - dl ) INSTALL(TARGETS ${TARGET_CYNARA} DESTINATION ${BIN_INSTALL_DIR}) -- 2.7.4 From ae42834191f7652728b1570ad9a9959a3dad1692 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Mon, 17 Nov 2014 09:34:17 +0100 Subject: [PATCH 15/16] Add missing devel package dependency libcynara-admin-devel package requires cynara-error.h that is provided by libcynara-client-commons-devel. Change-Id: Ic6b9203e2dcf80fd0057fa64d906819be69b929d Signed-off-by: Lukasz Wojciechowski --- packaging/cynara.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/cynara.spec b/packaging/cynara.spec index ae98c80..fa7fa23 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -112,6 +112,7 @@ admin client library for setting, listing and removing policies %package -n libcynara-admin-devel Summary: Cynara - admin client library (devel) Requires: libcynara-admin = %{version}-%{release} +Requires: libcynara-client-commons-devel = %{version}-%{release} Requires: libcynara-commons-devel = %{version}-%{release} %description -n libcynara-admin-devel -- 2.7.4 From 84252f505c6dac16aa0e73d4cf35313d5ba90a90 Mon Sep 17 00:00:00 2001 From: Lukasz Wojciechowski Date: Mon, 17 Nov 2014 09:38:42 +0100 Subject: [PATCH 16/16] Expose ClientSession type ClientSession is required by client-plugin mechanism. Files section for libcynara-commons-devel was enhanced, so it provides ClientSession.h Change-Id: Ia0d935bf297bdf1743fd37e5df3a0826ebf446cd Signed-off-by: Lukasz Wojciechowski --- packaging/cynara.spec | 1 + src/common/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/packaging/cynara.spec b/packaging/cynara.spec index fa7fa23..9869482 100644 --- a/packaging/cynara.spec +++ b/packaging/cynara.spec @@ -522,6 +522,7 @@ fi %files -n libcynara-commons-devel %{_includedir}/cynara/cynara-policy-types.h %{_includedir}/cynara/plugin/ExternalPluginInterface.h +%{_includedir}/cynara/types/ClientSession.h %{_includedir}/cynara/types/PolicyResult.h %{_includedir}/cynara/types/PolicyType.h %{_libdir}/libcynara-commons.so diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index bd3911f..68bda47 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -94,6 +94,7 @@ TARGET_LINK_LIBRARIES(${TARGET_CYNARA_COMMON} INSTALL(TARGETS ${TARGET_CYNARA_COMMON} DESTINATION ${LIB_INSTALL_DIR}) INSTALL(FILES + ${COMMON_PATH}/types/ClientSession.h ${COMMON_PATH}/types/PolicyResult.h ${COMMON_PATH}/types/PolicyType.h DESTINATION ${INCLUDE_INSTALL_DIR}/cynara/types -- 2.7.4