m_callback(checkId, cynara_async_call_cause::CYNARA_CALL_CAUSE_ANSWER, response, m_userData);
}
+void ResponseCallback::onCancel(cynara_check_id checkId) const {
+ if (!m_callback)
+ return;
+ m_callback(checkId, cynara_async_call_cause::CYNARA_CALL_CAUSE_CANCEL, 0, m_userData);
+}
+
void ResponseCallback::onFinish(cynara_check_id checkId) const {
if (!m_callback)
return;
~ResponseCallback() {};
void onAnswer(cynara_check_id checkId, int response) const;
- // MOCKUP
+ void onCancel(cynara_check_id checkId) const;
void onFinish(cynara_check_id checkId) const;
void onDisconnected(cynara_check_id checkId) const;
{
public:
CheckData(const PolicyKey &key, const std::string &session, const ResponseCallback &callback)
- : m_key(key), m_session(session), m_callback(callback) {}
+ : m_key(key), m_session(session), m_callback(callback), m_cancelled(false) {}
~CheckData() {}
const PolicyKey &key(void) const {
return m_callback;
}
+ bool cancelled(void) const {
+ return m_cancelled;
+ }
+
+ void cancel(void) {
+ m_cancelled = true;
+ }
+
private:
PolicyKey m_key;
std::string m_session;
ResponseCallback m_callback;
- // MOCKUP
+ bool m_cancelled;
};
} // namespace Cynara
#include <log/log.h>
#include <plugins/NaiveInterpreter.h>
#include <protocol/ProtocolClient.h>
+#include <request/CancelRequest.h>
#include <request/CheckRequest.h>
+#include <response/CancelResponse.h>
#include <response/CheckResponse.h>
#include <sockets/Socket.h>
#include <sockets/SocketPath.h>
}
Logic::~Logic() {
- for (auto &kv : m_checks)
- kv.second.callback().onFinish(kv.first);
+ for (auto &kv : m_checks) {
+ if (!kv.second.cancelled())
+ kv.second.callback().onFinish(kv.first);
+ }
m_statusCallback.onDisconnected();
}
}
}
-int Logic::cancelRequest(cynara_check_id checkId UNUSED) {
+int Logic::cancelRequest(cynara_check_id checkId) {
if (!ensureConnection())
return CYNARA_API_SERVICE_NOT_AVAILABLE;
- // MOCKUP
+ auto it = m_checks.find(checkId);
+ if (it == m_checks.end() || it->second.cancelled())
+ return CYNARA_API_SUCCESS;
+
+ m_socketClient->appendRequest(std::make_shared<CancelRequest>(it->first));
+
+ it->second.cancel();
+ it->second.callback().onCancel(it->first);
+ m_statusCallback.onStatusChange(m_socketClient->getSockFd(),
+ cynara_async_status::CYNARA_STATUS_FOR_RW);
+
return CYNARA_API_SUCCESS;
}
}
void Logic::prepareRequestsToSend(void) {
- for (auto &kv : m_checks) {
- // MOCKUP
- m_socketClient->appendRequest(std::make_shared<CheckRequest>(kv.second.key(), kv.first));
+ for (auto it = m_checks.begin(); it != m_checks.end();) {
+ if (it->second.cancelled()) {
+ m_sequenceContainer.release(it->first);
+ it = m_checks.erase(it);
+ } else {
+ m_socketClient->appendRequest(std::make_shared<CheckRequest>(it->second.key(), it->first));
+ ++it;
+ }
}
}
auto it = m_checks.find(checkResponse->sequenceNumber());
if (it == m_checks.end()) {
- LOGC("Critical error. Unknown response received: sequenceNumber = [%" PRIu16 "]",
+ LOGC("Critical error. Unknown checkResponse received: sequenceNumber = [%" PRIu16 "]",
checkResponse->sequenceNumber());
throw UnexpectedErrorException("Unexpected response from cynara service");
}
int result = m_cache->update(it->second.session(), it->second.key(),
checkResponse->m_resultRef);
- // MOCKUP
- it->second.callback().onAnswer(static_cast<cynara_check_id>(it->first), result);
+ if (!it->second.cancelled())
+ it->second.callback().onAnswer(static_cast<cynara_check_id>(it->first), result);
+ m_sequenceContainer.release(it->first);
+ m_checks.erase(it);
+}
+
+void Logic::processCancelResponse(CancelResponsePtr cancelResponse) {
+ LOGD("cancelResponse");
+
+ auto it = m_checks.find(cancelResponse->sequenceNumber());
+ if (it == m_checks.end()) {
+ LOGC("Critical error. Unknown cancelResponse received: sequenceNumber = [%" PRIu16 "]",
+ cancelResponse->sequenceNumber());
+ throw UnexpectedErrorException("Unexpected response from cynara service");
+ }
+ if (!it->second.cancelled()) {
+ LOGC("Critical error. CancelRequest not sent: sequenceNumber = [%" PRIu16 "]",
+ cancelResponse->sequenceNumber());
+ throw UnexpectedErrorException("Unexpected response from cynara service");
+ }
m_sequenceContainer.release(it->first);
m_checks.erase(it);
}
void Logic::processResponses(void) {
ResponsePtr response;
CheckResponsePtr checkResponse;
- while (true) {
- response = m_socketClient->getResponse();
- if (!response)
- break;
-
+ CancelResponsePtr cancelResponse;
+ while (response = m_socketClient->getResponse()) {
checkResponse = std::dynamic_pointer_cast<CheckResponse>(response);
if (checkResponse) {
processCheckResponse(checkResponse);
continue;
}
- // MOCKUP
- LOGC("Critical error. Casting Response to CheckResponse failed.");
+
+ cancelResponse = std::dynamic_pointer_cast<CancelResponse>(response);
+ if (cancelResponse) {
+ processCancelResponse(cancelResponse);
+ continue;
+ }
+
+ LOGC("Critical error. Casting Response to known response failed.");
throw UnexpectedErrorException("Unexpected response from cynara service");
}
}
void Logic::onServiceNotAvailable(void)
{
- for (auto &kv : m_checks)
- kv.second.callback().onDisconnected(kv.first);
+ for (auto &kv : m_checks) {
+ if (!kv.second.cancelled())
+ kv.second.callback().onDisconnected(kv.first);
+ }
m_checks.clear();
m_sequenceContainer.clear();
}
cynara_async_status socketDataStatus(void);
bool processOut(void);
void processCheckResponse(CheckResponsePtr checkResponse);
+ void processCancelResponse(CancelResponsePtr cancelResponse);
void processResponses(void);
bool processIn(void);
bool ensureConnection(void);
${COMMON_PATH}/protocol/ProtocolSerialization.cpp
${COMMON_PATH}/protocol/ProtocolSignal.cpp
${COMMON_PATH}/request/AdminCheckRequest.cpp
+ ${COMMON_PATH}/request/CancelRequest.cpp
${COMMON_PATH}/request/CheckRequest.cpp
${COMMON_PATH}/request/InsertOrUpdateBucketRequest.cpp
${COMMON_PATH}/request/RemoveBucketRequest.cpp
${COMMON_PATH}/request/RequestTaker.cpp
${COMMON_PATH}/request/SetPoliciesRequest.cpp
${COMMON_PATH}/request/SignalRequest.cpp
+ ${COMMON_PATH}/response/CancelResponse.cpp
${COMMON_PATH}/response/CheckResponse.cpp
${COMMON_PATH}/response/CodeResponse.cpp
${COMMON_PATH}/response/ResponseTaker.cpp
#include <protocol/ProtocolFrameSerializer.h>
#include <protocol/ProtocolOpCode.h>
#include <protocol/ProtocolSerialization.h>
+#include <request/CancelRequest.h>
#include <request/CheckRequest.h>
#include <request/RequestContext.h>
+#include <response/CancelResponse.h>
#include <response/CheckResponse.h>
#include <types/PolicyKey.h>
#include <types/PolicyResult.h>
return std::make_shared<ProtocolClient>();
}
+RequestPtr ProtocolClient::deserializeCancelRequest(ProtocolFrameHeader &frame) {
+ LOGD("Deserialized CancelRequest");
+ return std::make_shared<CancelRequest>(frame.sequenceNumber());
+}
+
RequestPtr ProtocolClient::deserializeCheckRequest(ProtocolFrameHeader &frame) {
std::string clientId, userId, privilegeId;
switch (opCode) {
case OpCheckPolicyRequest:
return deserializeCheckRequest(m_frameHeader);
+ case OpCancelRequest:
+ return deserializeCancelRequest(m_frameHeader);
default:
throw InvalidProtocolException(InvalidProtocolException::WrongOpCode);
break;
return nullptr;
}
+ResponsePtr ProtocolClient::deserializeCancelResponse(ProtocolFrameHeader &frame) {
+ LOGD("Deserialized CancelResponse");
+ return std::make_shared<CancelResponse>(frame.sequenceNumber());
+}
+
ResponsePtr ProtocolClient::deserializeCheckResponse(ProtocolFrameHeader &frame) {
PolicyType result;
PolicyResult::PolicyMetadata additionalInfo;
switch (opCode) {
case OpCheckPolicyResponse:
return deserializeCheckResponse(m_frameHeader);
+ case OpCancelResponse:
+ return deserializeCancelResponse(m_frameHeader);
default:
throw InvalidProtocolException(InvalidProtocolException::WrongOpCode);
break;
return nullptr;
}
+void ProtocolClient::execute(RequestContextPtr context, CancelRequestPtr request) {
+ ProtocolFramePtr frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber());
+
+ LOGD("Serializing CancelRequest op [%" PRIu8 "]", OpCancelRequest);
+
+ ProtocolSerialization::serialize(*frame, OpCancelRequest);
+
+ ProtocolFrameSerializer::finishSerialization(frame, context->responseQueue());
+}
+
void ProtocolClient::execute(RequestContextPtr context, CheckRequestPtr request) {
ProtocolFramePtr frame = ProtocolFrameSerializer::startSerialization(request->sequenceNumber());
ProtocolFrameSerializer::finishSerialization(frame, context->responseQueue());
}
+void ProtocolClient::execute(RequestContextPtr context, CancelResponsePtr response) {
+ ProtocolFramePtr frame = ProtocolFrameSerializer::startSerialization(
+ response->sequenceNumber());
+
+ LOGD("Serializing CancelResponse: op [%" PRIu8 "]", OpCancelResponse);
+
+ ProtocolSerialization::serialize(*frame, OpCancelResponse);
+
+ ProtocolFrameSerializer::finishSerialization(frame, context->responseQueue());
+}
+
void ProtocolClient::execute(RequestContextPtr context, CheckResponsePtr response) {
ProtocolFramePtr frame = ProtocolFrameSerializer::startSerialization(
response->sequenceNumber());
virtual RequestPtr extractRequestFromBuffer(BinaryQueue &bufferQueue);
virtual ResponsePtr extractResponseFromBuffer(BinaryQueue &bufferQueue);
+ virtual void execute(RequestContextPtr context, CancelRequestPtr request);
virtual void execute(RequestContextPtr context, CheckRequestPtr request);
+
+ virtual void execute(RequestContextPtr context, CancelResponsePtr response);
virtual void execute(RequestContextPtr context, CheckResponsePtr response);
private:
+ RequestPtr deserializeCancelRequest(ProtocolFrameHeader &frame);
RequestPtr deserializeCheckRequest(ProtocolFrameHeader &frame);
+
+ ResponsePtr deserializeCancelResponse(ProtocolFrameHeader &frame);
ResponsePtr deserializeCheckResponse(ProtocolFrameHeader &frame);
};
/** Client operations */
OpCheckPolicyRequest = 0,
OpCheckPolicyResponse,
+ OpCancelRequest,
+ OpCancelResponse,
- /** Opcodes 2 - 19 are reserved for future use */
+ /** Opcodes 4 - 19 are reserved for future use */
/** Admin operations */
OpInsertOrUpdateBucket = 20,
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file src/common/request/CancelRequest.cpp
+ * @author Marcin Niesluchowski <m.niesluchow@samsung.com>
+ * @version 1.0
+ * @brief This file implements cancel request class
+ */
+
+#include <memory>
+
+#include "CancelRequest.h"
+
+namespace Cynara {
+
+void CancelRequest::execute(RequestPtr self, RequestTakerPtr taker,
+ RequestContextPtr context) const {
+ taker->execute(context, std::dynamic_pointer_cast<CancelRequest>(self));
+}
+
+} // namespace Cynara
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file src/common/request/CancelRequest.h
+ * @author Marcin Niesluchowski <m.niesluchow@samsung.com>
+ * @version 1.0
+ * @brief This file defines cancel request class
+ */
+
+#ifndef SRC_COMMON_REQUEST_CANCELREQUEST_H_
+#define SRC_COMMON_REQUEST_CANCELREQUEST_H_
+
+#include <request/pointers.h>
+#include <request/Request.h>
+#include <request/RequestTaker.h>
+
+namespace Cynara {
+
+class CancelRequest : public Request {
+public:
+ CancelRequest(ProtocolFrameSequenceNumber sequenceNumber) : Request(sequenceNumber) {
+ }
+
+ virtual ~CancelRequest() {};
+
+ virtual void execute(RequestPtr self, RequestTakerPtr taker, RequestContextPtr context) const;
+};
+
+} // namespace Cynara
+
+#endif /* SRC_COMMON_REQUEST_CANCELREQUEST_H_ */
throw NotImplementedException();
}
+void RequestTaker::execute(RequestContextPtr context UNUSED, CancelRequestPtr request UNUSED) {
+ throw NotImplementedException();
+}
+
void RequestTaker::execute(RequestContextPtr context UNUSED, CheckRequestPtr request UNUSED) {
throw NotImplementedException();
}
virtual ~RequestTaker() {};
virtual void execute(RequestContextPtr context, AdminCheckRequestPtr request);
+ virtual void execute(RequestContextPtr context, CancelRequestPtr request);
virtual void execute(RequestContextPtr context, CheckRequestPtr request);
virtual void execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request);
virtual void execute(RequestContextPtr context, RemoveBucketRequestPtr request);
class AdminCheckRequest;
typedef std::shared_ptr<AdminCheckRequest> AdminCheckRequestPtr;
+class CancelRequest;
+typedef std::shared_ptr<CancelRequest> CancelRequestPtr;
+
class CheckRequest;
typedef std::shared_ptr<CheckRequest> CheckRequestPtr;
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file src/common/response/CancelResponse.cpp
+ * @author Marcin Niesluchowski <m.niesluchow@samsung.com>
+ * @version 1.0
+ * @brief This file implements cancel response class
+ */
+
+#include <memory>
+
+#include "CancelResponse.h"
+
+namespace Cynara {
+
+void CancelResponse::execute(ResponsePtr self, ResponseTakerPtr taker,
+ RequestContextPtr context) const {
+ taker->execute(context, std::dynamic_pointer_cast<CancelResponse>(self));
+}
+
+} // namespace Cynara
--- /dev/null
+/*
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file src/common/response/CancelResponse.h
+ * @author Marcin Niesluchowski <m.niesluchow@samsung.com>
+ * @version 1.0
+ * @brief This file defines response class for cancel response
+ */
+
+#ifndef SRC_COMMON_RESPONSE_CANCELRESPONSE_H_
+#define SRC_COMMON_RESPONSE_CANCELRESPONSE_H_
+
+#include <request/pointers.h>
+#include <response/pointers.h>
+#include <response/Response.h>
+
+namespace Cynara {
+
+class CancelResponse : public Response {
+public:
+ CancelResponse(ProtocolFrameSequenceNumber sequenceNumber) : Response(sequenceNumber) {
+ }
+
+ virtual ~CancelResponse() {};
+
+ virtual void execute(ResponsePtr self, ResponseTakerPtr taker, RequestContextPtr context) const;
+};
+
+} // namespace Cynara
+
+#endif /* SRC_COMMON_RESPONSE_CANCELRESPONSE_H_ */
namespace Cynara {
+void ResponseTaker::execute(RequestContextPtr context UNUSED, CancelResponsePtr response UNUSED) {
+ throw NotImplementedException();
+}
+
void ResponseTaker::execute(RequestContextPtr context UNUSED, CheckResponsePtr response UNUSED) {
throw NotImplementedException();
}
ResponseTaker() = default;
virtual ~ResponseTaker() {};
+ virtual void execute(RequestContextPtr context, CancelResponsePtr response);
virtual void execute(RequestContextPtr context, CheckResponsePtr response);
virtual void execute(RequestContextPtr context, CodeResponsePtr response);
};
namespace Cynara {
+class CancelResponse;
+typedef std::shared_ptr<CancelResponse> CancelResponsePtr;
+
class CheckResponse;
typedef std::shared_ptr<CheckResponse> CheckResponsePtr;
#include <main/Cynara.h>
#include <request/AdminCheckRequest.h>
+#include <request/CancelRequest.h>
#include <request/CheckRequest.h>
#include <request/InsertOrUpdateBucketRequest.h>
#include <request/RemoveBucketRequest.h>
#include <request/RequestContext.h>
#include <request/SetPoliciesRequest.h>
#include <request/SignalRequest.h>
+#include <response/CancelResponse.h>
#include <response/CheckResponse.h>
#include <response/CodeResponse.h>
#include <storage/Storage.h>
request->sequenceNumber()));
}
+void Logic::execute(RequestContextPtr context, CancelRequestPtr request) {
+ // MOCKUP
+ context->returnResponse(context, std::make_shared<CancelResponse>(request->sequenceNumber()));
+}
+
void Logic::execute(RequestContextPtr context, CheckRequestPtr request) {
PolicyResult result(PredefinedPolicyType::DENY);
if (check(context, request->key(), result)) {
}
virtual void execute(RequestContextPtr context, AdminCheckRequestPtr request);
+ virtual void execute(RequestContextPtr context, CancelRequestPtr request);
virtual void execute(RequestContextPtr context, CheckRequestPtr request);
virtual void execute(RequestContextPtr context, InsertOrUpdateBucketRequestPtr request);
virtual void execute(RequestContextPtr context, RemoveBucketRequestPtr request);