/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include <common.h>
#include <config/PathConfig.h>
+#include <containers/MutexedBinaryQueue.h>
#include <log/log.h>
#include <protocol/Protocol.h>
#include <protocol/ProtocolAgent.h>
Logic::Logic(const AgentType &agentType) : m_agentType(agentType),
m_socketClient(PathConfig::SocketPath::agent, std::make_shared<ProtocolAgent>()) {
m_responseTakerPtr = std::make_shared<ProtocolAgent>();
- m_responseBuffer = std::make_shared<BinaryQueue>();
+ m_responseBuffer = std::make_shared<MutexedBinaryQueue>();
if (!m_notify.init()) {
LOGW("Couldn't initialize notification object.");
return;
}
AgentActionRequest request(responseType, pluginData, sequenceNumber);
- m_responseBuffer->clear();
+ m_responseBuffer->lock()->clear();
RequestContext context(ResponseTakerPtr(), m_responseBuffer);
request.execute(*m_responseTakerPtr, context);
- return m_socketClient.sendDataToServer(*m_responseBuffer) ? CYNARA_API_SUCCESS :
- CYNARA_API_SERVICE_NOT_AVAILABLE;
+ auto lockedResponseBuffer = m_responseBuffer->lock();
+ return m_socketClient.sendDataToServer(lockedResponseBuffer) ?
+ CYNARA_API_SUCCESS : CYNARA_API_SERVICE_NOT_AVAILABLE;
}
int Logic::cancelWaiting(void) {
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include <types/Agent.h>
#include <api/ApiInterface.h>
+#include <containers/MutexedBinaryQueue.h>
#include <socket/AgentSocketClient.h>
namespace Cynara {
AgentSocketClient m_socketClient;
RequestTakerPtr m_responseTakerPtr;
- BinaryQueuePtr m_responseBuffer;
+ MutexedBinaryQueuePtr m_responseBuffer;
FdNotifyObject m_notify;
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include <sys/ioctl.h>
#include <unistd.h>
+#include <containers/MutexedBinaryQueue.h>
#include <error/SafeStrError.h>
#include <log/log.h>
#include <protocol/Protocol.h>
AgentSocketClient::AgentSocketClient(const std::string &socketPath, ProtocolPtr protocol)
: m_socket(socketPath), m_protocol(protocol), m_notifyFd(-1) {
- m_writeQueue = std::make_shared<BinaryQueue>();
+ m_writeQueue = std::make_shared<MutexedBinaryQueue>();
m_readQueue = std::make_shared<BinaryQueue>();
}
request.execute(*m_protocol, context);
//send request to cynara
- if (!sendDataToServer(*m_writeQueue)) {
+ auto lockedWriteQueue = m_writeQueue->lock();
+ if (!sendDataToServer(lockedWriteQueue)) {
return nullptr;
}
return response;
}
-bool AgentSocketClient::sendDataToServer(BinaryQueue &data) {
- if (m_socket.sendToServer(data) == Socket::SendStatus::CONNECTION_LOST) {
+bool AgentSocketClient::sendDataToServer(MutexedBinaryQueue::LockedBinaryQueue &data) {
+ if (m_socket.sendToServer(*data) == Socket::SendStatus::CONNECTION_LOST) {
LOGW("Error sending data to Cynara. Service not available.");
return false;
}
void AgentSocketClient::resetState(void) {
m_readQueue->clear();
- m_writeQueue->clear();
+ m_writeQueue->lock()->clear();
}
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include <string>
#include <containers/BinaryQueue.h>
+#include <containers/MutexedBinaryQueue.h>
#include <protocol/Protocol.h>
#include <request/pointers.h>
#include <response/pointers.h>
ResponsePtr getBufferedResponse(void);
ResponsePtr receiveResponseFromServer(void);
- bool sendDataToServer(BinaryQueue &data);
+ bool sendDataToServer(MutexedBinaryQueue::LockedBinaryQueue &data);
ResponsePtr askCynaraServer(const Request &request);
private:
Socket m_socket;
ProtocolPtr m_protocol;
BinaryQueuePtr m_readQueue;
- BinaryQueuePtr m_writeQueue;
+ MutexedBinaryQueuePtr m_writeQueue;
int m_notifyFd;
void resetState(void);
-# Copyright (c) 2015-2020 Samsung Electronics Co., Ltd All Rights Reserved
+# Copyright (c) 2015-2024 Samsung Electronics Co., Ltd All Rights Reserved
#
# This file is licensed under the terms of MIT License or the Apache License
# Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
${CHSGEN_PATH}/main.cpp
${CYNARA_EXTERNAL_SRC_PATH}/md5.c
${CYNARA_EXTERNAL_SRC_PATH}/md5wrapper.cpp
+ ${CYNARA_PATH}/common/error/SafeStrError.cpp
)
INCLUDE_DIRECTORIES(
/*
- * Copyright (c) 2015-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include <unistd.h>
#include <cynara-error.h>
+#include <error/SafeStrError.h>
#include <md5wrapper.h>
#include "ChecksumGenerator.h"
int err = errno;
if (err == ENOSYS) {
std::cerr << "'crypt' function was not implemented; error [" << err << "] : <"
- << strerror(err) << ">" << std::endl;
+ << safeStrError(err) << ">" << std::endl;
} else {
- std::cerr << "'crypt' function error [" << err << "] : <" << strerror(err) << ">"
+ std::cerr << "'crypt' function error [" << err << "] : <" << safeStrError(err) << ">"
<< std::endl;
}
- throw std::runtime_error(strerror(err));
+ throw std::runtime_error(safeStrError(err));
}
}
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
* client
*/
+#include <containers/MutexedBinaryQueue.h>
#include <request/Request.h>
#include <request/RequestContext.h>
SocketClientAsync::SocketClientAsync(const std::string &socketPath, ProtocolPtr protocol)
: m_socket(socketPath, 0), m_protocol(protocol) {
m_readQueue = std::make_shared<BinaryQueue>();
- m_writeQueue = std::make_shared<BinaryQueue>();
+ m_writeQueue = std::make_shared<MutexedBinaryQueue>();
}
Socket::ConnectionStatus SocketClientAsync::connect(void) {
}
bool SocketClientAsync::isDataToSend(void) {
- return m_socket.isDataToSend() || !m_writeQueue->empty();
+ return m_socket.isDataToSend() || !m_writeQueue->lock()->empty();
}
Socket::SendStatus SocketClientAsync::sendToCynara(void) {
- return m_socket.sendToServer(*m_writeQueue);
+ return m_socket.sendToServer(*m_writeQueue->lock());
}
bool SocketClientAsync::receiveFromCynara(void) {
void SocketClientAsync::clear(void)
{
m_readQueue->clear();
- m_writeQueue->clear();
+ m_writeQueue->lock()->clear();
}
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include <memory>
#include <string>
-#include <containers/BinaryQueue.h>
+#include <containers/MutexedBinaryQueue.h>
#include <protocol/Protocol.h>
#include <request/pointers.h>
#include <response/pointers.h>
Socket m_socket;
ProtocolPtr m_protocol;
BinaryQueuePtr m_readQueue;
- BinaryQueuePtr m_writeQueue;
+ MutexedBinaryQueuePtr m_writeQueue;
void clear(void);
};
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * This file is licensed under the terms of MIT License or the Apache License
+ * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
+ * See the LICENSE file or the notice below for Apache License Version 2.0
+ * details.
+ *
+ * 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/containers/MutexedBinaryQueue.h
+ * @author Krzysztof Małysa <k.malysa@samsung.com>
+ * @version 1.0
+ * @brief This file is the header and implementation file of binary queue with mutex
+ */
+
+#pragma once
+
+#include <memory>
+#include <mutex>
+#include <utility>
+
+#include "BinaryQueue.h"
+
+namespace Cynara {
+
+class MutexedBinaryQueue;
+
+using MutexedBinaryQueuePtr = std::shared_ptr<MutexedBinaryQueue>;
+using MutexedBinaryQueueWeakPtr = std::weak_ptr<MutexedBinaryQueue>;
+
+class MutexedBinaryQueue {
+public:
+ explicit MutexedBinaryQueue(BinaryQueuePtr ptr = std::make_shared<BinaryQueue>())
+ : m_mutex{std::make_shared<std::mutex>()}, m_binaryQueue{std::move(ptr)} {}
+
+ struct LockedBinaryQueue : public BinaryQueuePtr {
+ LockedBinaryQueue(std::shared_ptr<std::mutex> mtx, BinaryQueuePtr binaryQueue)
+ : BinaryQueuePtr{std::move(binaryQueue)}, m_mutex{std::move(mtx)}, m_guard{*m_mutex} {}
+
+ private:
+ std::shared_ptr<std::mutex> m_mutex;
+ std::lock_guard<std::mutex> m_guard;
+ };
+
+ LockedBinaryQueue lock() { return {m_mutex, m_binaryQueue}; }
+
+private:
+ std::shared_ptr<std::mutex> m_mutex;
+ BinaryQueuePtr m_binaryQueue;
+};
+
+} // namespace Cynara
/*
- * Copyright (c) 2014-2023 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
m_pluginLibs.push_back(std::move(handlePtr));
}
+std::unique_ptr<PluginManagerReadOnlyCopy> PluginManager::clone() const {
+ return std::make_unique<PluginManagerReadOnlyCopy>(getPolicyDescriptions());
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
namespace Cynara {
typedef std::shared_ptr<ExternalPluginInterface> ExternalPluginPtr;
+class PluginManagerReadOnlyCopy;
+
class PluginManager {
public:
PluginManager(const std::string &pluginDir);
void checkPolicyType(PolicyType pType) const;
+ std::unique_ptr<PluginManagerReadOnlyCopy> clone() const;
+
private:
typedef std::unique_ptr<void, std::function<void (void*)>> PluginLibPtr;
typedef std::list<PluginLibPtr> PluginLibs;
void openPlugin(const std::string &path);
};
+class PluginManagerReadOnlyCopy {
+public:
+ explicit PluginManagerReadOnlyCopy(std::vector<PolicyDescription> descriptions)
+ : m_descriptions{std::move(descriptions)} {}
+
+ const std::vector<PolicyDescription>& getPolicyDescriptions() const noexcept {
+ return m_descriptions;
+ }
+
+private:
+ std::vector<PolicyDescription> m_descriptions;
+};
+
} // namespace Cynara
#endif /* SRC_COMMON_PLUGIN_PLUGINMANAGER_H_ */
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
ProtocolSerialization::serialize(frame, request.startBucket());
ProtocolSerialization::serialize(frame, request.recursive());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context, const DescriptionListRequest &request) {
ProtocolSerialization::serialize(frame, OpDescriptionListRequest);
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context, const EraseRequest &request) {
ProtocolSerialization::serialize(frame, request.recursive());
ProtocolSerialization::serialize(frame, request.filter());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context,
ProtocolSerialization::serialize(frame, request.bucketId());
ProtocolSerialization::serialize(frame, request.result());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context, const ListRequest &request) {
ProtocolSerialization::serialize(frame, request.bucket());
ProtocolSerialization::serialize(frame, request.filter());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context, const RemoveBucketRequest &request) {
ProtocolSerialization::serialize(frame, OpRemoveBucket);
ProtocolSerialization::serialize(frame, request.bucketId());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context, const SetPoliciesRequest &request) {
ProtocolSerialization::serialize(frame, request.policiesToBeInsertedOrUpdated());
ProtocolSerialization::serialize(frame, request.policiesToBeRemoved());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context, const AdminCheckResponse &response) {
ProtocolSerialization::serialize(frame, response.isBucketValid());
ProtocolSerialization::serialize(frame, response.isDbCorrupted());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context, const CodeResponse &response) {
ProtocolSerialization::serialize(frame, OpCodeResponse);
ProtocolSerialization::serialize(frame, static_cast<ProtocolResponseCode>(response.m_code));
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context, const DescriptionListResponse &response)
ProtocolSerialization::serialize(frame, response.descriptions());
ProtocolSerialization::serialize(frame, response.isDbCorrupted());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAdmin::execute(const RequestContext &context, const ListResponse &response) {
ProtocolSerialization::serialize(frame, response.isBucketValid());
ProtocolSerialization::serialize(frame, response.isDbCorrupted());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
ProtocolSerialization::serialize(frame, request.type());
ProtocolSerialization::serialize(frame, request.data());
- ProtocolFrameSerializer::finishSerialization(frame, *context.responseQueue());
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAgent::execute(const RequestContext &context, const AgentRegisterRequest &request) {
ProtocolSerialization::serialize(frame, OpAgentRegisterRequest);
ProtocolSerialization::serialize(frame, request.agentType());
- ProtocolFrameSerializer::finishSerialization(frame, *context.responseQueue());
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAgent::execute(const RequestContext &context, const AgentRegisterResponse &response) {
ProtocolSerialization::serialize(frame, OpAgentRegisterResponse);
ProtocolSerialization::serialize(frame, static_cast<ProtocolResponseCode>(response.m_code));
- ProtocolFrameSerializer::finishSerialization(frame, *context.responseQueue());
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolAgent::execute(const RequestContext &context, const AgentActionResponse &response) {
ProtocolSerialization::serialize(frame, response.type());
ProtocolSerialization::serialize(frame, response.data());
- ProtocolFrameSerializer::finishSerialization(frame, *context.responseQueue());
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
ProtocolSerialization::serialize(frame, OpCancelRequest);
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolClient::execute(const RequestContext &context, const CheckRequest &request) {
ProtocolSerialization::serialize(frame, OpCheckPolicyRequest);
ProtocolSerialization::serialize(frame, request.key());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolClient::execute(const RequestContext &context, const SimpleCheckRequest &request) {
ProtocolSerialization::serialize(frame, OpSimpleCheckPolicyRequest);
ProtocolSerialization::serialize(frame, request.key());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolClient::execute(const RequestContext &context,
ProtocolSerialization::serialize(frame, OpMonitorEntriesPutRequest);
ProtocolSerialization::serialize(frame, request.monitorEntries());
- ProtocolFrameSerializer::finishSerialization(frame, *context.responseQueue());
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolClient::execute(const RequestContext &context, const MonitorEntryPutRequest &request) {
const auto &entry = request.monitorEntry();
ProtocolSerialization::serialize(frame, OpMonitorEntryPutRequest);
ProtocolSerialization::serialize(frame, entry);
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolClient::execute(const RequestContext &context, const CancelResponse &response) {
ProtocolSerialization::serialize(frame, OpCancelResponse);
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolClient::execute(const RequestContext &context, const CheckResponse &response) {
ProtocolSerialization::serialize(frame, response.m_resultRef.policyType());
ProtocolSerialization::serialize(frame, response.m_resultRef.metadata());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolClient::execute(const RequestContext &context, const SimpleCheckResponse &response) {
ProtocolSerialization::serialize(frame, response.getResult().policyType());
ProtocolSerialization::serialize(frame, response.getResult().metadata());
- ProtocolFrameSerializer::finishSerialization(frame, *(context.responseQueue()));
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
} // namespace Cynara
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
ProtocolSerialization::serialize(frame, OpMonitorGetEntriesRequest);
ProtocolSerialization::serialize(frame,
static_cast<ProtocolFrameFieldsCount>(request.bufferSize()));
- ProtocolFrameSerializer::finishSerialization(frame, *context.responseQueue());
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolMonitorGet::execute(const RequestContext &context,
ProtocolFrame frame = ProtocolFrameSerializer::startSerialization(request.sequenceNumber());
ProtocolSerialization::serialize(frame, OpMonitorGetFlushRequest);
- ProtocolFrameSerializer::finishSerialization(frame, *context.responseQueue());
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
void ProtocolMonitorGet::execute(const RequestContext &context,
ProtocolSerialization::serializeCustomLimit(frame, response.entries(),
CYNARA_MAX_MONITOR_BUFFER_SIZE);
- ProtocolFrameSerializer::finishSerialization(frame, *context.responseQueue());
+ ProtocolFrameSerializer::finishSerialization(frame,
+ *context.responseQueue()->lock());
}
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool AdminCheckRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
}
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool AgentActionRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
+
private:
const AgentRequestType m_type;
const RawBuffer m_data;
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool AgentRegisterRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
+
private:
AgentType m_agentType;
};
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool CancelRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual ~CancelRequest() {};
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool CheckRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
}
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool DescriptionListRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual ~DescriptionListRequest() {};
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool EraseRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
+
private:
PolicyBucketId m_startBucket;
bool m_recursive;
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool InsertOrUpdateBucketRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
}
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool ListRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
}
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool MonitorEntriesPutRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
+
const std::vector<MonitorEntry> &monitorEntries(void) const {
return m_monitorEntries;
}
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool MonitorEntryPutRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
+
const MonitorEntry &monitorEntry(void) const {
return m_monitorEntry;
}
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool MonitorGetEntriesRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
+
private:
const size_t m_bufferSize;
};
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool MonitorGetFlushRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual ~MonitorGetFlushRequest() {};
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool RemoveBucketRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
}
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#define SRC_COMMON_REQUEST_REQUEST_H_
#include <request/pointers.h>
+#include <request/RequestContext.h>
+#include <request/RequestTaker.h>
#include <types/ProtocolFields.h>
namespace Cynara {
virtual void execute(RequestTaker &taker, const RequestContext &context) const = 0;
+ virtual bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const = 0;
+
ProtocolFrameSequenceNumber sequenceNumber(void) const {
return m_sequenceNumber;
}
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#ifndef SRC_COMMON_REQUEST_REQUESTCONTEXT_H_
#define SRC_COMMON_REQUEST_REQUESTCONTEXT_H_
-#include <containers/BinaryQueue.h>
+#include <containers/MutexedBinaryQueue.h>
#include <exceptions/ContextErrorException.h>
#include <request/pointers.h>
#include <response/pointers.h>
typedef int ClientId;
static const int InvalidClientId = -1;
- RequestContext(ResponseTakerPtr responseTaker, BinaryQueuePtr responseQueue,
+ RequestContext(ResponseTakerPtr responseTaker, MutexedBinaryQueuePtr responseQueue,
ClientId clientId = InvalidClientId)
: m_responseTaker(responseTaker), m_responseQueue(responseQueue), m_clientId(clientId) {
}
response.execute(*taker, *this);
}
- BinaryQueuePtr responseQueue(void) const {
+ MutexedBinaryQueuePtr responseQueue(void) const {
auto bbqPtr = m_responseQueue.lock();
if (bbqPtr)
return bbqPtr;
private:
ResponseTakerWeakPtr m_responseTaker;
- BinaryQueueWeakPtr m_responseQueue;
+ MutexedBinaryQueueWeakPtr m_responseQueue;
ClientId m_clientId;
};
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual void contextClosed(const RequestContext &context);
};
+class ReadOnlyRequestTaker : public RequestTaker {
+public:
+ virtual bool canBeExecutedReadOnly(const AdminCheckRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const AgentActionRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const AgentRegisterRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const CancelRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const CheckRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const DescriptionListRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const EraseRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const InsertOrUpdateBucketRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const ListRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const MonitorGetEntriesRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const MonitorGetFlushRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const MonitorEntriesPutRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const MonitorEntryPutRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const RemoveBucketRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const SetPoliciesRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const SignalRequest &request) const = 0;
+ virtual bool canBeExecutedReadOnly(const SimpleCheckRequest &request) const = 0;
+};
+
} // namespace Cynara
#endif /* SRC_COMMON_REQUEST_REQUESTTAKER_H_ */
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool SetPoliciesRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
}
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool SignalRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
+
uint32_t signalNumber(void) const {
return m_sigInfo.ssi_signo;
}
/*
- * Copyright (c) 2015-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2015-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
taker.execute(context, *this);
}
+bool SimpleCheckRequest::canBeExecutedReadOnly(const ReadOnlyRequestTaker &taker) const {
+ return taker.canBeExecutedReadOnly(*this);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2015-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2015-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
}
virtual void execute(RequestTaker &taker, const RequestContext &context) const;
+
+ bool canBeExecutedReadOnly(const ReadOnlyRequestTaker& taker) const override;
};
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
SocketClient::SocketClient(const std::string &socketPath, ProtocolPtr protocol)
: m_socket(socketPath), m_protocol(protocol) {
- m_writeQueue = std::make_shared<BinaryQueue>();
+ m_writeQueue = std::make_shared<MutexedBinaryQueue>();
m_readQueue = std::make_shared<BinaryQueue>();
}
request.execute(*m_protocol, context);
//send request to cynara
- if (m_socket.sendToServer(*m_writeQueue) == Socket::SendStatus::CONNECTION_LOST) {
+ if (m_socket.sendToServer(*m_writeQueue->lock()) ==
+ Socket::SendStatus::CONNECTION_LOST) {
LOGW("Disconnected while sending request to Cynara.");
return nullptr;
}
request.execute(*m_protocol, context);
//send request to cynara
- if (m_socket.sendToServer(*m_writeQueue) == Socket::SendStatus::CONNECTION_LOST) {
+ if (m_socket.sendToServer(*m_writeQueue->lock()) ==
+ Socket::SendStatus::CONNECTION_LOST) {
LOGW("Disconnected while sending request to Cynara.");
return false;
}
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include <memory>
#include <string>
-#include <containers/BinaryQueue.h>
+#include <containers/MutexedBinaryQueue.h>
#include <protocol/Protocol.h>
#include <request/pointers.h>
#include <response/pointers.h>
Socket m_socket;
ProtocolPtr m_protocol;
BinaryQueuePtr m_readQueue;
- BinaryQueuePtr m_writeQueue;
+ MutexedBinaryQueuePtr m_writeQueue;
public:
SocketClient(const std::string &socketPath, ProtocolPtr protocol);
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved.
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd. All rights reserved.
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#ifndef SRC_COMMON_TYPES_LINK_H_
#define SRC_COMMON_TYPES_LINK_H_
-#include <containers/BinaryQueue.h>
+#include <containers/MutexedBinaryQueue.h>
namespace Cynara {
-typedef BinaryQueuePtr LinkId;
+typedef MutexedBinaryQueuePtr LinkId;
} // namespace Cynara
/*
- * Copyright (c) 2016-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2016-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* Contact: Lukasz Wojciechowski <l.wojciechow@partner.samsung.com>
*
*/
#include <cerrno>
-#include <cstdio>
-#include <cstring>
#include <fcntl.h>
+#include <memory>
#include <poll.h>
#include <unistd.h>
#include <config/PathConfig.h>
+#include <containers/MutexedBinaryQueue.h>
#include <error/SafeStrError.h>
#include <log/log.h>
#include <request/Request.h>
std::lock_guard<std::mutex> lock(m_mutex);
//pass request to protocol
BinaryQueuePtr bbqSharedPtr(&m_writeQueue, [](BinaryQueue *) {});
- RequestContext context(ResponseTakerPtr(), bbqSharedPtr);
+ auto mbbqSharedPtr = std::make_shared<MutexedBinaryQueue>(bbqSharedPtr);
+
+ RequestContext context(ResponseTakerPtr(), mbbqSharedPtr);
request.execute(m_protocol, context);
//send request to cynara
-# Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+# Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
#
# This file is licensed under the terms of MIT License or the Apache License
# Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
TARGET_LINK_LIBRARIES(${TARGET_CYNARA}
${CYNARA_COMMON_AND_STORAGE_LIB}
${CYNARA_DEP_LIBRARIES}
+ pthread
)
INSTALL(TARGETS ${TARGET_CYNARA} DESTINATION ${BIN_DIR})
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
* @brief This file implements main class of logic layer in cynara service
*/
+#include <cassert>
#include <csignal>
#include <cinttypes>
-#include <functional>
#include <memory>
#include <vector>
switch (request.signalNumber()) {
case SIGTERM:
LOGI("SIGTERM received!");
- m_socketManager->mainLoopStop();
+ m_socketManager->signalStopMainLoop();
break;
}
}
-void Logic::execute(const RequestContext &context, const AdminCheckRequest &request) {
- PolicyResult result;
- bool bucketValid = true;
-
- if (m_dbCorrupted) {
- bucketValid = false;
- } else {
- try {
- result = m_storage->checkPolicy(request.key(), request.startBucket(),
- request.recursive());
- } catch (const BucketNotExistsException &ex) {
- bucketValid = false;
- }
- }
-
- context.returnResponse(AdminCheckResponse(result, bucketValid, m_dbCorrupted,
- request.sequenceNumber()));
+void Logic::execute(const RequestContext &/*context*/, const AdminCheckRequest &/*request*/) {
+ auto msg = std::string("This function (") + __PRETTY_FUNCTION__ + ") should not be called";
+ LOGE(msg.c_str());
+ throw UnexpectedErrorException{std::move(msg)};
}
void Logic::execute(const RequestContext &context, const AgentActionRequest &request) {
}
result = (m_dbCorrupted ? PredefinedPolicyType::DENY : m_storage->checkPolicy(key));
-
- switch (result.policyType()) {
- case PredefinedPolicyType::ALLOW :
- LOGD("check of policy key <%s> returned ALLOW", key.toString().c_str());
- return true;
- case PredefinedPolicyType::DENY :
- LOGD("check of policy key <%s> returned DENY", key.toString().c_str());
- return true;
- }
-
+ // result was already checked in canBeExecutedReadOnly(const CheckRequest&)
+ assert(result.policyType() != PredefinedPolicyType::ALLOW);
+ assert(result.policyType() != PredefinedPolicyType::DENY);
return pluginCheck(context, key, checkId, result);
}
return false;
}
-void Logic::execute(const RequestContext &context, const DescriptionListRequest &request) {
- auto descriptions = m_pluginManager->getPolicyDescriptions();
- descriptions.insert(descriptions.begin(), predefinedPolicyDescr.begin(),
- predefinedPolicyDescr.end());
- context.returnResponse(DescriptionListResponse(descriptions, m_dbCorrupted,
- request.sequenceNumber()));
+void Logic::execute(const RequestContext &/*context*/, const DescriptionListRequest &/*request*/) {
+ auto msg = std::string("This function (") + __PRETTY_FUNCTION__ + ") should not be called";
+ LOGE(msg.c_str());
+ throw UnexpectedErrorException{std::move(msg)};
}
void Logic::execute(const RequestContext &context, const EraseRequest &request) {
context.returnResponse(CodeResponse(code, request.sequenceNumber()));
}
-void Logic::execute(const RequestContext &context, const ListRequest &request) {
- bool bucketValid = true;
- std::vector<Policy> policies;
-
- if (m_dbCorrupted) {
- bucketValid = false;
- } else {
- try {
- policies = m_storage->listPolicies(request.bucket(), request.filter());
- } catch (const BucketNotExistsException &ex) {
- bucketValid = false;
- }
- }
-
- context.returnResponse(ListResponse(policies, bucketValid, m_dbCorrupted,
- request.sequenceNumber()));
+void Logic::execute(const RequestContext &/*context*/, const ListRequest &/*request*/) {
+ auto msg = std::string("This function (") + __PRETTY_FUNCTION__ + ") should not be called";
+ LOGE(msg.c_str());
+ throw UnexpectedErrorException{std::move(msg)};
}
void Logic::execute(const RequestContext &context, const RemoveBucketRequest &request) {
PolicyKey key = request.key();
result = m_storage->checkPolicy(key);
- switch (result.policyType()) {
- case PredefinedPolicyType::ALLOW:
- LOGD("simple check of policy key <%s> returned ALLOW", key.toString().c_str());
- break;
- case PredefinedPolicyType::DENY:
- LOGD("simple check of policy key <%s> returned DENY", key.toString().c_str());
- break;
- default: {
+ // result was already checked in canBeExecutedReadOnly
+ assert(result.policyType() != PredefinedPolicyType::ALLOW);
+ assert(result.policyType() != PredefinedPolicyType::DENY);
+
+ [&] {
ExternalPluginPtr plugin = m_pluginManager->getPlugin(result.policyType());
if (!plugin) {
LOGE("Plugin not found for policy: [0x%x]", result.policyType());
result = PolicyResult(PredefinedPolicyType::DENY);
retValue = CYNARA_API_SUCCESS;
- break;
+ return;
}
ServicePluginInterfacePtr servicePlugin =
LOGE("Couldn't cast plugin pointer to ServicePluginInterface");
result = PolicyResult(PredefinedPolicyType::DENY);
retValue = CYNARA_API_SUCCESS;
- break;
+ return;
}
AgentType requiredAgent;
switch (ret) {
case ServicePluginInterface::PluginStatus::ANSWER_READY:
LOGD("simple check of policy key <%s> in plugin returned [" PRIu16 "]",
- key.toString().c_str(), result.policyType());
+ key.toString().c_str(), result.policyType());
break;
case ServicePluginInterface::PluginStatus::ANSWER_NOTREADY:
retValue = CYNARA_API_ACCESS_NOT_RESOLVED;
result = PolicyResult(PredefinedPolicyType::DENY);
retValue = CYNARA_API_SUCCESS;
}
- }
- }
+ }();
+
m_auditLog.log(request.key(), result);
context.returnResponse(SimpleCheckResponse(retValue, result,
request.sequenceNumber()));
void Logic::onPoliciesChanged(void) {
m_storage->save();
- m_socketManager->disconnectAllClients();
+ m_socketManager->signalDisconnectAllClients();
m_pluginManager->invalidateAll();
//todo remove all saved contexts (if there will be any saved contexts)
}
}
}
+std::unique_ptr<ReadOnlyLogic> Logic::createReadOnlyCopy() {
+ return std::make_unique<ReadOnlyLogic>(m_dbCorrupted, m_storage->clone(),
+ m_pluginManager->clone());
+}
+
+ReadOnlyLogic::ReadOnlyLogic(bool dbCorrupted, std::unique_ptr<StorageReadOnlyCopy> storageClone,
+ std::unique_ptr<PluginManagerReadOnlyCopy> pluginManagerClone)
+ : m_dbCorrupted{dbCorrupted}, m_storageClone{std::move(storageClone)},
+ m_pluginManagerClone{std::move(pluginManagerClone)} {}
+
+void ReadOnlyLogic::execute(const RequestContext &context,
+ const AdminCheckRequest &request) {
+ PolicyResult result;
+ bool bucketValid = true;
+
+ if (m_dbCorrupted) {
+ bucketValid = false;
+ } else {
+ try {
+ result = m_storageClone->checkPolicy(request.key(), request.startBucket(),
+ request.recursive());
+ } catch (const BucketNotExistsException &ex) {
+ bucketValid = false;
+ }
+ }
+
+ context.returnResponse(AdminCheckResponse(result, bucketValid, m_dbCorrupted,
+ request.sequenceNumber()));
+}
+
+void ReadOnlyLogic::execute(const RequestContext &context, const CheckRequest &request) {
+ const auto& key = request.key();
+
+ auto result = (m_dbCorrupted ? PredefinedPolicyType::DENY : m_storageClone->checkPolicy(key));
+ // result was already checked in canBeExecutedReadOnly
+ m_auditLog.log(key, result);
+ context.returnResponse(CheckResponse(result, request.sequenceNumber()));
+}
+
+void ReadOnlyLogic::execute(const RequestContext &context, const DescriptionListRequest &request) {
+ auto descriptions = m_pluginManagerClone->getPolicyDescriptions();
+ descriptions.insert(descriptions.begin(), predefinedPolicyDescr.begin(),
+ predefinedPolicyDescr.end());
+ context.returnResponse(DescriptionListResponse(descriptions, m_dbCorrupted,
+ request.sequenceNumber()));
+}
+
+void ReadOnlyLogic::execute(const RequestContext &context, const ListRequest &request) {
+ bool bucketValid = true;
+ std::vector<Policy> policies;
+
+ if (m_dbCorrupted) {
+ bucketValid = false;
+ } else {
+ try {
+ policies = m_storageClone->listPolicies(request.bucket(), request.filter());
+ } catch (const BucketNotExistsException &ex) {
+ bucketValid = false;
+ }
+ }
+
+ context.returnResponse(ListResponse(policies, bucketValid, m_dbCorrupted,
+ request.sequenceNumber()));
+}
+
+void ReadOnlyLogic::execute(const RequestContext &context,
+ const SimpleCheckRequest &request) {
+
+ int retValue = CYNARA_API_SUCCESS;
+ PolicyResult result;
+ PolicyKey key = request.key();
+ result = m_storageClone->checkPolicy(key);
+
+ switch (result.policyType()) {
+ case PredefinedPolicyType::ALLOW:
+ LOGD("simple check of policy key <%s> returned ALLOW", key.toString().c_str());
+ break;
+ case PredefinedPolicyType::DENY:
+ LOGD("simple check of policy key <%s> returned DENY", key.toString().c_str());
+ break;
+ default: {
+ auto msg = std::string("This function (") + __PRETTY_FUNCTION__ +
+ ") should not be called with this parameters";
+ LOGE(msg.c_str());
+ throw UnexpectedErrorException{std::move(msg)};
+ }
+ }
+ m_auditLog.log(request.key(), result);
+ context.returnResponse(SimpleCheckResponse(retValue, result,
+ request.sequenceNumber()));
+}
+
+void ReadOnlyLogic::contextClosed(const RequestContext &/*context*/) {
+ auto msg = std::string("This function (") + __PRETTY_FUNCTION__ + ") should not be called";
+ LOGE(msg.c_str());
+ throw UnexpectedErrorException{std::move(msg)};
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const AdminCheckRequest &/*request*/) const {
+ return true;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const AgentActionRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const AgentRegisterRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const CancelRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const CheckRequest &request) const {
+ PolicyResult result(PredefinedPolicyType::DENY);
+ const auto& key = request.key();
+
+ result = (m_dbCorrupted ? PredefinedPolicyType::DENY : m_storageClone->checkPolicy(key));
+
+ switch (result.policyType()) {
+ case PredefinedPolicyType::ALLOW:
+ case PredefinedPolicyType::DENY:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const DescriptionListRequest &/*request*/) const {
+ return true;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const EraseRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const InsertOrUpdateBucketRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const ListRequest &/*request*/) const {
+ return true;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const MonitorGetEntriesRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const MonitorGetFlushRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const MonitorEntriesPutRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const MonitorEntryPutRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const RemoveBucketRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const SetPoliciesRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const SignalRequest &/*request*/) const {
+ return false;
+}
+
+bool ReadOnlyLogic::canBeExecutedReadOnly(const SimpleCheckRequest &request) const {
+ PolicyResult result;
+ PolicyKey key = request.key();
+ result = m_storageClone->checkPolicy(key);
+
+ switch (result.policyType()) {
+ case PredefinedPolicyType::ALLOW:
+ case PredefinedPolicyType::DENY:
+ return true;
+ default:
+ return false;
+ }
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#define SRC_SERVICE_LOGIC_LOGIC_H_
#include <map>
+#include <memory>
#include <vector>
#include <log/AuditLog.h>
#include <request/CheckRequestManager.h>
#include <request/pointers.h>
#include <request/RequestTaker.h>
+#include <storage/Storage.h>
#include <cynara-plugin.h>
namespace Cynara {
+class ReadOnlyLogic;
+
class Logic : public RequestTaker {
public:
Logic();
virtual void contextClosed(const RequestContext &context);
virtual void loadDb(void);
-private:
+ virtual std::unique_ptr<ReadOnlyLogic> createReadOnlyCopy();
+
+protected:
AgentManagerPtr m_agentManager;
CheckRequestManager m_checkRequestManager;
PluginManagerPtr m_pluginManager;
void onPoliciesChanged(void);
};
+class ReadOnlyLogic : public ReadOnlyRequestTaker {
+public:
+ ReadOnlyLogic(bool dbCorrupted, std::unique_ptr<StorageReadOnlyCopy> storageClone,
+ std::unique_ptr<PluginManagerReadOnlyCopy> pluginManagerClone);
+
+ void execute(const RequestContext &context, const AdminCheckRequest &request) override;
+ void execute(const RequestContext &context, const CheckRequest &request) override;
+ void execute(const RequestContext &context, const DescriptionListRequest &request) override;
+ void execute(const RequestContext &context, const ListRequest &request) override;
+ void execute(const RequestContext &context, const SimpleCheckRequest &request) override;
+
+ void contextClosed(const RequestContext &context) override;
+
+ bool canBeExecutedReadOnly(const AdminCheckRequest &request) const override;
+ bool canBeExecutedReadOnly(const AgentActionRequest &request) const override;
+ bool canBeExecutedReadOnly(const AgentRegisterRequest &request) const override;
+ bool canBeExecutedReadOnly(const CancelRequest &request) const override;
+ bool canBeExecutedReadOnly(const CheckRequest &request) const override;
+ bool canBeExecutedReadOnly(const DescriptionListRequest &request) const override;
+ bool canBeExecutedReadOnly(const EraseRequest &request) const override;
+ bool canBeExecutedReadOnly(const InsertOrUpdateBucketRequest &request) const override;
+ bool canBeExecutedReadOnly(const ListRequest &request) const override;
+ bool canBeExecutedReadOnly(const MonitorGetEntriesRequest &request) const override;
+ bool canBeExecutedReadOnly(const MonitorGetFlushRequest &request) const override;
+ bool canBeExecutedReadOnly(const MonitorEntriesPutRequest &request) const override;
+ bool canBeExecutedReadOnly(const MonitorEntryPutRequest &request) const override;
+ bool canBeExecutedReadOnly(const RemoveBucketRequest &request) const override;
+ bool canBeExecutedReadOnly(const SetPoliciesRequest &request) const override;
+ bool canBeExecutedReadOnly(const SignalRequest &request) const override;
+ bool canBeExecutedReadOnly(const SimpleCheckRequest &request) const override;
+
+private:
+ AuditLog m_auditLog;
+ bool m_dbCorrupted;
+ std::unique_ptr<StorageReadOnlyCopy> m_storageClone;
+ std::unique_ptr<PluginManagerReadOnlyCopy> m_pluginManagerClone;
+};
+
} // namespace Cynara
#endif /* SRC_SERVICE_LOGIC_LOGIC_H_ */
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include "Descriptor.h"
+#include <containers/MutexedBinaryQueue.h>
+
namespace Cynara {
Descriptor::Descriptor() : m_listen(false), m_used(false), m_client(false), m_protocol(nullptr) {
void Descriptor::checkQueues(void) {
if (!m_writeQueue)
- m_writeQueue = std::make_shared<BinaryQueue>();
+ m_writeQueue = std::make_shared<MutexedBinaryQueue>();
if (!m_readQueue)
m_readQueue = std::make_shared<BinaryQueue>();
}
-BinaryQueuePtr Descriptor::writeQueue(void) {
+MutexedBinaryQueuePtr Descriptor::writeQueue(void) {
checkQueues();
return m_writeQueue;
}
bool Descriptor::hasDataToWrite(void) const {
- if (m_writeQueue)
- return !(m_writeQueue->empty() && m_writeBuffer.empty());
+ if (m_writeQueue) {
+ auto lockedWriteQueue = m_writeQueue->lock();
+ return !(lockedWriteQueue->empty() && m_writeBuffer.empty());
+ }
return false;
}
RawBuffer &Descriptor::prepareWriteBuffer(void) {
checkQueues();
- size_t queuedDataSize = m_writeQueue->size();
+ auto lockedWriteQueue = m_writeQueue->lock();
+
+ size_t queuedDataSize = lockedWriteQueue->size();
size_t bufferDataSize = m_writeBuffer.size();
m_writeBuffer.resize(queuedDataSize + bufferDataSize);
- m_writeQueue->flattenConsume(m_writeBuffer.data() + bufferDataSize, queuedDataSize);
+ lockedWriteQueue->flattenConsume(m_writeBuffer.data() + bufferDataSize, queuedDataSize);
return m_writeBuffer;
}
m_writeQueue.reset();
m_writeBuffer.clear();
m_protocol.reset();
+ ++m_generation;
}
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#ifndef SRC_SERVICE_SOCKETS_DESCRIPTOR_H_
#define SRC_SERVICE_SOCKETS_DESCRIPTOR_H_
-#include <memory>
+#include <cstdint>
#include <common.h>
+#include <containers/MutexedBinaryQueue.h>
#include <protocol/Protocol.h>
#include <request/Request.h>
#include <response/pointers.h>
return m_protocol;
}
+ const ProtocolPtr readOnlyProtocol(void) const {
+ return m_readOnlyProtocol;
+ }
+
ResponseTakerPtr responseTaker(void) const;
- BinaryQueuePtr writeQueue(void);
+ MutexedBinaryQueuePtr writeQueue(void);
void setProtocol(ProtocolPtr protocol) {
m_protocol = protocol;
}
+ void setReadOnlyProtocol(ProtocolPtr protocol) {
+ m_readOnlyProtocol = protocol;
+ }
+
void setListen(bool listen) {
m_listen = listen;
}
void clear(void);
+ uint64_t getGeneration() const noexcept {
+ return m_generation;
+ }
+
private:
bool m_listen;
bool m_used;
bool m_client;
+ // In a multithread server, one thread may produce the response to the request coming from some
+ // descriptor. But the descriptor may get reused in the meantime by the other thread.
+ // m_generation is for ensuring that such response will not be sent via the reused descriptor.
+ uint64_t m_generation = 0;
BinaryQueuePtr m_readQueue;
- BinaryQueuePtr m_writeQueue;
+ MutexedBinaryQueuePtr m_writeQueue;
RawBuffer m_writeBuffer;
ProtocolPtr m_protocol;
+ ProtocolPtr m_readOnlyProtocol;
void checkQueues(void);
};
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
* @brief This file implements socket layer manager for cynara
*/
+#include <csignal>
+#include <cstdint>
+#include <cstring>
#include <errno.h>
#include <fcntl.h>
#include <memory>
-#include <signal.h>
+#include <mutex>
+#include <sys/eventfd.h>
#include <sys/select.h>
#include <sys/signalfd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
+#include <utility>
+#include <variant>
#ifdef BUILD_WITH_SYSTEMD_DAEMON
#include <systemd/sd-daemon.h>
#endif
#include <attributes/attributes.h>
-#include <log/log.h>
#include <common.h>
#include <config/PathConfig.h>
+#include <error/SafeStrError.h>
#include <exceptions/DescriptorNotExistsException.h>
#include <exceptions/InitException.h>
#include <exceptions/UnexpectedErrorException.h>
+#include <log/log.h>
+#include <containers/BinaryQueue.h>
+#include <containers/MutexedBinaryQueue.h>
+#include <containers/RawBuffer.h>
#include <logic/Logic.h>
#include <main/Cynara.h>
#include <protocol/ProtocolAdmin.h>
#include <protocol/ProtocolSignal.h>
#include <request/pointers.h>
#include <request/RequestContext.h>
-#include <stdexcept>
+#include <response/pointers.h>
#include "SocketManager.h"
createDomainSocket(std::make_shared<ProtocolMonitorGet>(), PathConfig::SocketPath::monitorGet,
monitorSocketUMask, false);
createSignalSocket(std::make_shared<ProtocolSignal>());
+ createNonReadOnlyRequestResultsNumEventFd();
+ // Initialize RO logic
+ m_readOnlyLogic = m_logic->createReadOnlyCopy();
+
LOGI("SocketManger init done");
}
void SocketManager::mainLoop(void) {
LOGI("SocketManger mainLoop start");
+
+ m_nonReadOnlyWorkerThread = std::thread([this] {
+ for (;;) {
+ auto reqV = m_nonReadOnlyRequests.recv();
+ if (std::holds_alternative<NoMoreRequests>(reqV))
+ break; // No more requests
+
+ auto notifyTheMainThread = [&]{
+ uint64_t x = 1;
+ if (write(m_nonReadOnlyRequestResultsNumEventFd, &x, sizeof(x)) != sizeof(x)) {
+ int err = errno;
+ LOGE("write(m_nonReadOnlyRequestResultsNumEventFd) failed <%s>",
+ safeStrError(err).c_str());
+ }
+ };
+
+ if (std::holds_alternative<CloseContext>(reqV)) {
+ auto& req = std::get<CloseContext>(reqV);
+ m_logic->contextClosed(
+ RequestContext(nullptr, req.closedWriteQueue, req.closedSocketFd));
+ // Send result to the main thread
+ m_nonReadOnlyRequestResults.send(CloseContextResult{});
+ notifyTheMainThread();
+ continue;
+ }
+
+ if (std::holds_alternative<NonReadOnlyRequest>(reqV)) {
+ auto& req = std::get<NonReadOnlyRequest>(reqV);
+ LOGD("non-read-only logic worker thread: handling request with socket fd [%i] with"
+ " generation [%i] and sequence number [%i]", req.socketFd,
+ req.socketFdGeneration, static_cast<int>(req.request->sequenceNumber()));
+ // Execute the request.
+ auto context = RequestContext(req.protocol, req.writeQueue, req.socketFd);
+ req.request->execute(*m_logic, context);
+ LOGD("Response size: [%i]",
+ static_cast<int>(req.writeQueue->lock()->size()));
+ // Install new RO logic
+ {
+ auto readOnlyLogic = m_logic->createReadOnlyCopy();
+ auto readOnlyGuard = std::lock_guard{m_readOnlyLogicLock};
+ m_readOnlyLogic = std::move(readOnlyLogic);
+ }
+ LOGD("non-read-only logic worker thread: sending response to request with socket fd"
+ " [%i] with generation [%i] and sequence number [%i] of size [%i]",
+ req.socketFd, req.socketFdGeneration,
+ static_cast<int>(req.request->sequenceNumber()),
+ static_cast<int>(req.writeQueue->lock()->size()));
+ // Send result to the main thread
+ m_nonReadOnlyRequestResults.send(NonReadOnlyRequestResult{
+ req.socketFd,
+ req.socketFdGeneration,
+ std::exchange(m_needToDisconnectAllClients, false),
+ std::exchange(m_needToStopMainLoop, false),
+ });
+ notifyTheMainThread();
+ }
+ }
+ });
+
m_working = true;
while (m_working) {
fd_set readSet = m_readSet;
continue;
default:
int err = errno;
- throw UnexpectedErrorException(err, strerror(err));
+ throw UnexpectedErrorException(err, safeStrError(err));
}
} else if (ret > 0) {
for (int i = 0; i < m_maxDesc + 1 && ret; ++i) {
}
}
+ LOGD("checking sockets <= %i for data to write", m_maxDesc);
for (int i = 0; i < m_maxDesc + 1; ++i) {
- if (m_fds[i].isUsed() && m_fds[i].hasDataToWrite())
+ if (m_fds[i].isUsed() && m_fds[i].hasDataToWrite()) {
+ LOGD("socket [%i] has data to write", i);
addWriteSocket(i);
+ }
}
}
}
+
+ m_nonReadOnlyRequests.send(NoMoreRequests{});
+ m_nonReadOnlyWorkerThread.join();
+
LOGI("SocketManger mainLoop done");
}
void SocketManager::readyForRead(int fd) {
LOGD("SocketManger readyForRead on fd [%d] start", fd);
+
+ if (fd == m_nonReadOnlyRequestResultsNumEventFd) {
+ LOGD("SocketManager m_nonReadOnlyRequestResultsNumEventFd is ready for read");
+ uint64_t resNum = 0;
+ if (read(fd, &resNum, sizeof(resNum)) != sizeof(resNum)) {
+ int err = errno;
+ LOGE("Failed to read from eventfd <%s>", safeStrError(err).c_str());
+ throw UnexpectedErrorException(err, safeStrError(err));
+ }
+ for (uint64_t i = 0; i < resNum; ++i) {
+ auto resV = m_nonReadOnlyRequestResults.recv();
+ if (std::holds_alternative<CloseContextResult>(resV))
+ continue;
+
+ if (std::holds_alternative<NonReadOnlyRequestResult>(resV)) {
+ auto& res = std::get<NonReadOnlyRequestResult>(resV);
+ LOGD("main thread: handling response to request with socket fd [%i] with"
+ " generation [%i]",
+ res.socketFd, res.socketFdGeneration);
+ if (res.socketFd == -1)
+ continue;
+ // Handle the response
+ auto& desc = m_fds[res.socketFd];
+ if (desc.isUsed() && desc.getGeneration() == res.socketFdGeneration) {
+ // Descriptor was not closed and was not reused.
+ // Now we can safely read and process the other requests from the socket.
+ addReadSocket(res.socketFd);
+ // Process next requests if there are any on this socket
+ handleRead(res.socketFd, RawBuffer{});
+ }
+ // Process extra events
+ if (res.disconnectAllClients)
+ disconnectAllClients();
+ if (res.stopMainLoop)
+ mainLoopStop();
+ }
+ }
+ return;
+ }
+
auto &desc = m_fds[fd];
if (desc.isListen()) {
readyForAccept(fd);
return;
default:
LOGW("While reading from [%d] socket, error [%d]:<%s>",
- fd, err, strerror(err));
+ fd, err, safeStrError(err).c_str());
}
} else {
LOGN("Socket [%d] closed on other end", fd);
break;
case EPIPE:
default:
- LOGD("Error during write to fd [%d]:<%s> ", fd, strerror(err));
+ LOGD("Error during write to fd [%d]:<%s> ", fd, safeStrError(err).c_str());
closeSocket(fd);
break;
}
int clientFd = accept4(fd, (struct sockaddr*) &clientAddr, &clientLen, SOCK_NONBLOCK);
if (clientFd == -1) {
UNUSED int err = errno;
- LOGW("Error in accept on socket [%d]: <%s>", fd, strerror(err));
+ LOGW("Error in accept on socket [%d]: <%s>", fd, safeStrError(err).c_str());
return;
}
LOGD("Accept on sock [%d]. New client socket opened [%d]", fd, clientFd);
auto &desc = createDescriptor(clientFd, m_fds[fd].isClient());
desc.setListen(false);
desc.setProtocol(m_fds[fd].protocol()->clone());
+ desc.setReadOnlyProtocol(m_fds[fd].protocol()->clone());
addReadSocket(clientFd);
LOGD("SocketManger readyForAccept on fd [%d] done", fd);
}
void SocketManager::closeSocket(int fd) {
LOGD("SocketManger closeSocket fd [%d] start", fd);
Descriptor &desc = m_fds[fd];
- requestTaker()->contextClosed(RequestContext(nullptr, desc.writeQueue(), fd));
+ m_nonReadOnlyRequests.send(CloseContext{
+ fd,
+ desc.writeQueue(),
+ });
removeReadSocket(fd);
removeWriteSocket(fd);
desc.clear();
break;
LOGD("request extracted");
- //build context
- RequestContext context(desc.responseTaker(), desc.writeQueue(), fd);
- //pass request to request taker
- req->execute(*requestTaker(), context);
+ auto guard = std::unique_lock{m_readOnlyLogicLock};
+ if (req->canBeExecutedReadOnly(*m_readOnlyLogic)) {
+ LOGD("Executing request with read-only logic");
+ // Build context. dest.writeQueue() is safe to use since sockets for which request
+ // is handled in non-read-only worker thread are not read from during the request
+ // handling.
+ auto contextForROLogic = std::make_shared<RequestContext>(
+ desc.readOnlyProtocol(), desc.writeQueue(), fd);
+ // Pass request to the request taker.
+ req->execute(*m_readOnlyLogic, *contextForROLogic);
+ } else {
+ guard.unlock();
+ // Stop listening on the socket so that we don't have a situation where a read
+ // request comes after the write request, but we handle it before the write request
+ // finishes and return the answer based on the old policy. Or use desc.writeQueue()
+ // by read-only logic.
+ removeReadSocket(fd);
+
+ LOGD("Passing request to the non-read-only logic");
+ // Pass the request to the m_nonReadOnlyWorkerThread.
+ m_nonReadOnlyRequests.send(NonReadOnlyRequest{
+ fd,
+ desc.getGeneration(),
+ std::move(req),
+ desc.protocol(),
+ desc.writeQueue(),
+ });
+ break;
+ }
}
} catch (const Exception &ex) {
LOGE("Error handling request <%s>. Closing socket", ex.what());
auto &desc = createDescriptor(fd, client);
desc.setListen(true);
desc.setProtocol(protocol);
+ desc.setReadOnlyProtocol(protocol->clone());
addReadSocket(fd);
LOGD("Domain socket: [%d] added.", fd);
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
UNUSED int err = errno;
- LOGE("Error during UNIX socket creation: <%s>", strerror(err));
+ LOGE("Error during UNIX socket creation: <%s>", safeStrError(err).c_str());
throw InitException();
}
UNUSED int err = errno;
close(fd);
LOGE("Error setting \"O_NONBLOCK\" on descriptor [%d] with fcntl: <%s>",
- fd, strerror(err));
+ fd, safeStrError(err).c_str());
throw InitException();
}
UNUSED int err = errno;
close(fd);
LOGE("Error in bind socket descriptor [%d] to path <%s>: <%s>",
- fd, path.c_str(), strerror(err));
+ fd, path.c_str(), safeStrError(err).c_str());
throw InitException();
}
UNUSED int err = errno;
close(fd);
LOGE("Error setting listen on file descriptor [%d], path <%s>: <%s>",
- fd, path.c_str(), strerror(err));
+ fd, path.c_str(), safeStrError(err).c_str());
throw InitException();
}
sigaddset(&mask, SIGTERM); // systemd terminates service sending this signal
if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
- LOGE("sigprocmask failed: <%s>", strerror(errno));
+ LOGE("sigprocmask failed: <%s>", safeStrError(errno).c_str());
return;
}
int fd = signalfd(-1, &mask, SFD_NONBLOCK);
if (fd < 0) {
- LOGE("Creating signal file descriptor failed: <%s>", strerror(errno));
+ LOGE("Creating signal file descriptor failed: <%s>", safeStrError(errno).c_str());
return;
}
auto &desc = createDescriptor(fd, false);
desc.setListen(false);
desc.setProtocol(protocol);
+ desc.setReadOnlyProtocol(protocol->clone());
addReadSocket(fd);
LOGD("Signal socket: [%d] added.", fd);
}
+void SocketManager::createNonReadOnlyRequestResultsNumEventFd() {
+ int efd = eventfd(0, EFD_CLOEXEC);
+ if (efd < 0) {
+ int err = errno;
+ LOGE("eventfd() failed <%s>", safeStrError(err).c_str());
+ throw UnexpectedErrorException(err, safeStrError(err));
+ }
+ m_nonReadOnlyRequestResultsNumEventFd = efd;
+ // Mark the efd to be listened on for read events
+ auto& desc = createDescriptor(efd, false);
+ desc.setListen(false);
+ desc.setProtocol(nullptr);
+ desc.setReadOnlyProtocol(nullptr);
+ addReadSocket(efd);
+ LOGD("SocketManger created nonReadOnlyRequestResultsNumEventFd [%d]", efd);
+}
+
Descriptor &SocketManager::createDescriptor(int fd, bool client) {
if (fd > m_maxDesc) {
m_maxDesc = fd;
FD_CLR(fd, &m_writeSet);
}
-RequestTakerPtr SocketManager::requestTaker(void) {
- return std::static_pointer_cast<RequestTaker>(m_logic);
-}
-
void SocketManager::disconnectAllClients(void) {
for(int i = 0; i <= m_maxDesc; ++i) {
auto &desc = m_fds[i];
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#ifndef SRC_SERVICE_SOCKETS_SOCKETMANAGER_H_
#define SRC_SERVICE_SOCKETS_SOCKETMANAGER_H_
-#include <vector>
+#include <cstdio>
#include <memory>
-#include <stdio.h>
+#include <thread>
+#include <variant>
+#include <vector>
#include <common.h>
+#include <containers/MutexedBinaryQueue.h>
+#include <exceptions/UnexpectedErrorException.h>
#include <main/pointers.h>
#include <protocol/Protocol.h>
#include <request/RequestTaker.h>
#include "Descriptor.h"
+#include "logic/Logic.h"
+#include "utils/Channel.h"
namespace Cynara {
~SocketManager();
void run(void);
- void mainLoopStop(void);
void bindLogic(LogicPtr logic) {
m_logic = logic;
m_logic.reset();
}
- void disconnectAllClients(void);
+ // Only safe to call from m_nonReadOnlyWorkerThread
+ void signalDisconnectAllClients() {
+ if (std::this_thread::get_id() != m_nonReadOnlyWorkerThread.get_id())
+ throw UnexpectedErrorException{"signalDisconnectAllClients() call in the wrong thread"};
+ m_needToDisconnectAllClients = true;
+ }
+
+ // Only safe to call from m_nonReadOnlyWorkerThread
+ void signalStopMainLoop() {
+ if (std::this_thread::get_id() != m_nonReadOnlyWorkerThread.get_id())
+ throw UnexpectedErrorException{"signalDisconnectAllClients() call in the wrong thread"};
+ m_needToStopMainLoop = true;
+ }
private:
+ struct NoMoreRequests {};
+ struct NonReadOnlyRequest {
+ int socketFd;
+ uint64_t socketFdGeneration;
+ RequestPtr request;
+ ProtocolPtr protocol;
+ MutexedBinaryQueuePtr writeQueue;
+ };
+ struct CloseContext {
+ int closedSocketFd;
+ MutexedBinaryQueuePtr closedWriteQueue;
+ };
+
+ struct NonReadOnlyRequestResult {
+ int socketFd;
+ uint64_t socketFdGeneration;
+ bool disconnectAllClients;
+ bool stopMainLoop;
+ };
+ // Used to break the event loop and write the created responses
+ struct CloseContextResult {};
+
+ std::mutex m_readOnlyLogicLock;
+ std::unique_ptr<ReadOnlyLogic> m_readOnlyLogic;
+
LogicPtr m_logic;
+ std::thread m_nonReadOnlyWorkerThread;
+ Channel<std::variant<NoMoreRequests, NonReadOnlyRequest, CloseContext>> m_nonReadOnlyRequests;
+ Channel<std::variant<NonReadOnlyRequestResult, CloseContextResult>> m_nonReadOnlyRequestResults;
+ int m_nonReadOnlyRequestResultsNumEventFd = -1;
+ // Only accessed from m_nonReadOnlyWorkerThread
+ bool m_needToDisconnectAllClients = false;
+ bool m_needToStopMainLoop = false;
typedef std::vector<Descriptor> FDVector;
FDVector m_fds;
void init(void);
void mainLoop(void);
+ void mainLoopStop(void);
+
void readyForRead(int fd);
void readyForWrite(int fd);
void readyForAccept(int fd);
static int getSocketFromSystemD(const std::string &path);
#endif
void createSignalSocket(ProtocolPtr protocol);
+ void createNonReadOnlyRequestResultsNumEventFd();
Descriptor &createDescriptor(int fd, bool client);
void removeReadSocket(int fd);
void addWriteSocket(int fd);
void removeWriteSocket(int fd);
-
- RequestTakerPtr requestTaker(void);
+ void disconnectAllClients(void);
};
} // namespace Cynara
--- /dev/null
+/*
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * This file is licensed under the terms of MIT License or the Apache License
+ * Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
+ * See the LICENSE file or the notice below for Apache License Version 2.0
+ * details.
+ *
+ * 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/utils/Channel.h
+ * @author Krzysztof Małysa <k.malysa@samsung.com>
+ * @version 1.0
+ * @brief This file defines and implements a channel across threads
+ */
+
+#pragma once
+
+#include <condition_variable>
+#include <deque>
+#include <mutex>
+#include <utility>
+
+namespace Cynara {
+
+template<class T>
+class Channel {
+public:
+ Channel() = default;
+ ~Channel() = default;
+
+ Channel(const Channel&) = delete;
+ Channel(Channel&&) = delete;
+ Channel& operator=(const Channel&) = delete;
+ Channel& operator=(Channel&&) = delete;
+
+ void send(T&& msg) {
+ {
+ auto guard = std::lock_guard{m_lock};
+ m_messages.push_back(std::move(msg));
+ }
+ m_condVar.notify_one();
+ }
+
+ T recv() {
+ auto lock = std::unique_lock{m_lock};
+ m_condVar.wait(lock, [&] { return !m_messages.empty(); });
+ auto msg = std::move(m_messages.front());
+ m_messages.pop_front();
+ return msg;
+ }
+
+private:
+ std::mutex m_lock;
+ std::condition_variable m_condVar;
+ std::deque<T> m_messages;
+};
+
+} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
}
}
+std::unique_ptr<StorageBackend> InMemoryStorageBackend::clone() {
+ auto copy = std::make_unique<InMemoryStorageBackend>(m_dbPath);
+ copy->m_buckets = m_buckets;
+ return copy;
+}
+
void InMemoryStorageBackend::dumpDatabase(const std::shared_ptr<std::ofstream> &chsStream) {
auto indexStream = std::make_shared<ChecksumStream>(PathConfig::StoragePath::indexFilename,
chsStream);
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
virtual void erasePolicies(const PolicyBucketId &bucketId, bool recursive,
const PolicyKey &filter);
+ std::unique_ptr<StorageBackend> clone() override;
+
protected:
// Saves database as backup files and stores checksums to @p chsStream
void dumpDatabase(const std::shared_ptr<std::ofstream> &chsStream);
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include "Storage.h"
-namespace Cynara {
+namespace {
-PolicyResult Storage::checkPolicy(const PolicyKey &key,
- const PolicyBucketId &startBucketId /*= defaultPolicyBucketId*/,
- bool recursive /*= true*/) {
- auto policies = m_backend.searchBucket(startBucketId, key);
- return minimalPolicy(policies, key, recursive);
-};
-
-PolicyResult Storage::minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key,
- bool recursive) {
+Cynara::PolicyResult minimalPolicy(Cynara::StorageBackend& storageBackend,
+ const Cynara::PolicyBucket &bucket, const Cynara::PolicyKey &key,
+ bool recursive) {
bool hasMinimal = false;
- PolicyResult minimal = bucket.defaultPolicy();
+ Cynara::PolicyResult minimal = bucket.defaultPolicy();
- auto proposeMinimal = [&minimal, &hasMinimal](const PolicyResult &candidate) {
+ auto proposeMinimal = [&minimal, &hasMinimal](const Cynara::PolicyResult &candidate) {
if (hasMinimal == false) {
minimal = candidate;
} else if (candidate < minimal) {
const auto &policyResult = policy->result();
switch (policyResult.policyType()) {
- case PredefinedPolicyType::DENY:
+ case Cynara::PredefinedPolicyType::DENY:
return policyResult; // Do not expect lower value than DENY
- case PredefinedPolicyType::BUCKET: {
+ case Cynara::PredefinedPolicyType::BUCKET: {
if (recursive == true) {
- auto bucketResults = m_backend.searchBucket(policyResult.metadata(), key);
- auto minimumOfBucket = minimalPolicy(bucketResults, key, true);
- if (minimumOfBucket != PredefinedPolicyType::NONE) {
+ auto bucketResults = storageBackend.searchBucket(policyResult.metadata(),
+ key);
+ auto minimumOfBucket = minimalPolicy(storageBackend, bucketResults, key,
+ true);
+ if (minimumOfBucket != Cynara::PredefinedPolicyType::NONE) {
proposeMinimal(minimumOfBucket);
}
}
continue;
}
- case PredefinedPolicyType::ALLOW:
+ case Cynara::PredefinedPolicyType::ALLOW:
default:
break;
}
return minimal;
}
+} // namespace
+
+namespace Cynara {
+
+PolicyResult Storage::checkPolicy(const PolicyKey &key,
+ const PolicyBucketId &startBucketId /*= defaultPolicyBucketId*/,
+ bool recursive /*= true*/) {
+ auto policies = m_backend.searchBucket(startBucketId, key);
+ return minimalPolicy(m_backend, policies, key, recursive);
+}
+
void Storage::insertPolicies(const std::map<PolicyBucketId, std::vector<Policy>> &policiesByBucketId) {
auto pointedBucketExists = [this] (const Policy &policy) -> void {
m_backend.save();
}
+std::unique_ptr<StorageReadOnlyCopy> Storage::clone() {
+ return std::make_unique<StorageReadOnlyCopy>(m_backend.clone());
+}
+
+StorageReadOnlyCopy::StorageReadOnlyCopy(std::unique_ptr<StorageBackend> backend)
+ : m_backend{std::move(backend)} {}
+
+PolicyResult StorageReadOnlyCopy::checkPolicy(const PolicyKey &key,
+ const PolicyBucketId &startBucketId /*= defaultPolicyBucketId*/,
+ bool recursive /*= true*/) {
+ auto policies = m_backend->searchBucket(startBucketId, key);
+ return minimalPolicy(*m_backend, policies, key, recursive);
+}
+
+PolicyBucket::Policies StorageReadOnlyCopy::listPolicies(const PolicyBucketId &bucketId,
+ const PolicyKey &filter) const {
+ return m_backend->listPolicies(bucketId, filter);
+}
+
} // namespace Cynara
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#define SRC_STORAGE_STORAGE_H_
#include <map>
-#include <string>
+#include <memory>
#include <vector>
#include <types/Policy.h>
namespace Cynara {
+class StorageReadOnlyCopy;
+
class Storage
{
public:
void load(void);
void save(void);
-protected:
- PolicyResult minimalPolicy(const PolicyBucket &bucket, const PolicyKey &key, bool recursive);
+ std::unique_ptr<StorageReadOnlyCopy> clone();
private:
StorageBackend &m_backend; // backend strategy
};
+class StorageReadOnlyCopy {
+public:
+ explicit StorageReadOnlyCopy(std::unique_ptr<StorageBackend> backend);
+
+ PolicyResult checkPolicy(const PolicyKey &key,
+ const PolicyBucketId &startBucketId = defaultPolicyBucketId,
+ bool recursive = true);
+
+ PolicyBucket::Policies listPolicies(const PolicyBucketId &bucketId,
+ const PolicyKey &filter) const;
+
+private:
+ std::unique_ptr<StorageBackend> m_backend;
+};
+
} // namespace Cynara
#endif /* SRC_STORAGE_STORAGE_H_ */
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
const PolicyKey &filter) = 0;
virtual void load(void) = 0;
virtual void save(void) = 0;
+
+ virtual std::unique_ptr<StorageBackend> clone() = 0;
};
} /* namespace Cynara */
/*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2020-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
template <class Protocol, class Exception, class Message, class...MessageArg>
void testProtocolException(MessageArg&&...messageArg) {
- auto queue = std::make_shared<Cynara::BinaryQueue>();
+ auto queue = std::make_shared<Cynara::MutexedBinaryQueue>();
Cynara::RequestContext context(Cynara::ResponseTakerPtr(), queue);
Protocol protocol;
Message message(std::forward<MessageArg>(messageArg)...);
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include <gtest/gtest.h>
-#include <containers/BinaryQueue.h>
+#include <containers/MutexedBinaryQueue.h>
#include <containers/RawBuffer.h>
#include <protocol/Protocol.h>
#include <request/pointers.h>
template <typename R>
void testRequest(std::shared_ptr<R> request, Cynara::ProtocolPtr protocol) {
- auto queue = std::make_shared<Cynara::BinaryQueue>();
+ auto queue = std::make_shared<Cynara::MutexedBinaryQueue>();
Cynara::RequestContext context(Cynara::ResponseTakerPtr(), queue);
request->execute(*protocol, context);
- auto extractedRequest = protocol->extractRequestFromBuffer(queue);
+ auto extractedRequest = protocol->extractRequestFromBuffer(queue->lock());
ASSERT_TRUE(bool(extractedRequest));
- ASSERT_EQ(queue->size(), static_cast<size_t>(0));
+ ASSERT_EQ(queue->lock()->size(), static_cast<size_t>(0));
compare(*request, dynamic_cast<R &>(*extractedRequest));
}
void binaryTestRequest(Cynara::RequestPtr request, Cynara::ProtocolPtr protocol) {
- auto queue = std::make_shared<Cynara::BinaryQueue>();
+ auto queue = std::make_shared<Cynara::MutexedBinaryQueue>();
Cynara::RequestContext context(Cynara::ResponseTakerPtr(), queue);
request->execute(*protocol, context);
- Cynara::RawBuffer data(queue->size());
- queue->flatten(data.data(), queue->size());
+ Cynara::RawBuffer data(queue->lock()->size());
+ queue->lock()->flatten(data.data(), data.size());
- auto extractedRequest = protocol->extractRequestFromBuffer(queue);
+ auto extractedRequest = protocol->extractRequestFromBuffer(queue->lock());
ASSERT_TRUE(bool(extractedRequest));
- ASSERT_EQ(queue->size(), static_cast<size_t>(0));
+ ASSERT_EQ(queue->lock()->size(), static_cast<size_t>(0));
extractedRequest->execute(*protocol, context);
- Cynara::RawBuffer data2(queue->size());
- queue->flatten(data2.data(), queue->size());
+ Cynara::RawBuffer data2(queue->lock()->size());
+ queue->lock()->flatten(data2.data(), data2.size());
ASSERT_EQ(data, data2);
}
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
#include <gtest/gtest.h>
-#include <containers/BinaryQueue.h>
+#include <containers/MutexedBinaryQueue.h>
#include <containers/RawBuffer.h>
#include <protocol/Protocol.h>
#include <request/RequestContext.h>
template <typename R>
void testResponse(std::shared_ptr<R> response, Cynara::ProtocolPtr protocol) {
- auto queue = std::make_shared<Cynara::BinaryQueue>();
+ auto queue = std::make_shared<Cynara::MutexedBinaryQueue>();
auto context = Cynara::RequestContext(Cynara::ResponseTakerPtr(), queue);
response->execute(*protocol, context);
- auto extractedResponse = protocol->extractResponseFromBuffer(queue);
+ auto extractedResponse = protocol->extractResponseFromBuffer(queue->lock());
ASSERT_TRUE(bool(extractedResponse));
- ASSERT_EQ(queue->size(), static_cast<size_t>(0));
+ ASSERT_EQ(queue->lock()->size(), static_cast<size_t>(0));
compare(*response, dynamic_cast<R &>(*extractedResponse));
}
void binaryTestResponse(Cynara::ResponsePtr response, Cynara::ProtocolPtr protocol) {
- auto queue = std::make_shared<Cynara::BinaryQueue>();
+ auto queue = std::make_shared<Cynara::MutexedBinaryQueue>();
auto context = Cynara::RequestContext(Cynara::ResponseTakerPtr(), queue);
response->execute(*protocol, context);
- Cynara::RawBuffer data(queue->size());
- queue->flatten(data.data(), queue->size());
+ Cynara::RawBuffer data(queue->lock()->size());
+ queue->lock()->flatten(data.data(), data.size());
- auto extractedResponse = protocol->extractResponseFromBuffer(queue);
+ auto extractedResponse = protocol->extractResponseFromBuffer(queue->lock());
ASSERT_TRUE(bool(extractedResponse));
- ASSERT_EQ(queue->size(), static_cast<size_t>(0));
+ ASSERT_EQ(queue->lock()->size(), static_cast<size_t>(0));
extractedResponse->execute(*protocol, context);
- Cynara::RawBuffer data2(queue->size());
- queue->flatten(data2.data(), queue->size());
+ Cynara::RawBuffer data2(queue->lock()->size());
+ queue->lock()->flatten(data2.data(), data2.size());
ASSERT_EQ(data, data2);
}
/*
- * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2024 Samsung Electronics Co., Ltd All Rights Reserved
*
* This file is licensed under the terms of MIT License or the Apache License
* Version 2.0 of your choice. See the LICENSE.MIT file for MIT license details.
const PolicyKey &filter));
MOCK_METHOD3(erasePolicies, void(const PolicyBucketId &bucketId, bool recursive,
const PolicyKey &filter));
+
+ MOCK_METHOD0(clone, std::unique_ptr<StorageBackend>(void));
};
#endif /* FAKESTORAGEBACKEND_H_ */