summaryrefslogtreecommitdiff
path: root/src/components/application_manager/src/request_info.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/application_manager/src/request_info.cc')
-rw-r--r--src/components/application_manager/src/request_info.cc315
1 files changed, 301 insertions, 14 deletions
diff --git a/src/components/application_manager/src/request_info.cc b/src/components/application_manager/src/request_info.cc
index 0b448c9e4..26af81ea5 100644
--- a/src/components/application_manager/src/request_info.cc
+++ b/src/components/application_manager/src/request_info.cc
@@ -1,4 +1,4 @@
-/**
+/*
* \file request_info.h
* \brief request information structure source file.
*
@@ -29,38 +29,43 @@
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "application_manager/request_info.h"
+
+#include <algorithm>
namespace application_manager {
namespace request_controller {
+CREATE_LOGGERPTR_GLOBAL(logger_, "RequestController");
+
+uint32_t RequestInfo::HmiConnectoinKey = 0;
+
HMIRequestInfo::HMIRequestInfo(
RequestPtr request,
const uint64_t timeout_sec):
- RequestInfo(timeout_sec),
- request_(request) {
+ RequestInfo(request, HMIRequest, timeout_sec) {
correlation_id_ = request_->correlation_id();
+ app_id_ = RequestInfo::HmiConnectoinKey;
}
HMIRequestInfo::HMIRequestInfo(
RequestPtr request,
const TimevalStruct &start_time,
const uint64_t timeout_sec):
- RequestInfo(start_time, timeout_sec),
- request_(request) {
+ RequestInfo(request, HMIRequest, start_time, timeout_sec) {
correlation_id_ = request_->correlation_id();
+ app_id_ = RequestInfo::HmiConnectoinKey;
}
MobileRequestInfo::MobileRequestInfo(
RequestPtr request,
const uint64_t timeout_sec):
- RequestInfo(timeout_sec),
- request_(request) {
- mobile_correlation_id_ = request_.get()->correlation_id();
+ RequestInfo(request, MobileRequest, timeout_sec) {
+ correlation_id_ = request_.get()->correlation_id();
app_id_ = request_.get()->connection_key();
}
@@ -68,12 +73,294 @@ MobileRequestInfo::MobileRequestInfo(
RequestPtr request,
const TimevalStruct &start_time,
const uint64_t timeout_sec):
- RequestInfo(start_time, timeout_sec),
- request_(request) {
- mobile_correlation_id_ = request_.get()->correlation_id();
+ RequestInfo(request, MobileRequest, start_time, timeout_sec) {
+ correlation_id_ = request_.get()->correlation_id();
app_id_ = request_.get()->connection_key();
}
-} // namespace request_controller
+RequestInfo::RequestInfo(RequestPtr request,
+ const RequestInfo::RequestType requst_type,
+ const TimevalStruct& start_time,
+ const uint64_t timeout_sec):
+ request_(request),
+ start_time_(start_time),
+ timeout_sec_(timeout_sec) {
+ updateEndTime();
+ requst_type_ = requst_type;
+ correlation_id_ = request_->correlation_id();
+ app_id_ = request_->connection_key();
+}
+
+void application_manager::request_controller::RequestInfo::updateEndTime() {
+ end_time_ = date_time::DateTime::getCurrentTime();
+ end_time_.tv_sec += timeout_sec_;
+
+ // possible delay during IPC
+ const uint32_t hmi_delay_sec = 1;
+ end_time_.tv_sec += hmi_delay_sec;
+}
+
+void RequestInfo::updateTimeOut(const uint64_t& timeout_sec) {
+ timeout_sec_ = timeout_sec;
+ updateEndTime();
+}
+
+bool RequestInfo::isExpired() {
+ TimevalStruct curr_time = date_time::DateTime::getCurrentTime();
+ return end_time_.tv_sec <= curr_time.tv_sec;
+ // TODO(AKutsan) APPLINK-9711 Need to use compareTime method when timer will support millisecconds
+ // return date_time::GREATER == date_time::DateTime::compareTime(end_time_, curr_time);
+}
+
+uint64_t RequestInfo::hash() {
+ return GenerateHash(app_id(), requestId());
+}
+
+uint64_t RequestInfo::GenerateHash(uint32_t var1, uint32_t var2) {
+ uint64_t hash_result = 0;
+ hash_result = var1;
+ hash_result = hash_result << 32;
+ hash_result = hash_result | var2;
+ return hash_result;
+}
+
+FakeRequestInfo::FakeRequestInfo(uint32_t app_id, uint32_t correaltion_id) {
+ app_id_ = app_id;
+ correlation_id_ = correaltion_id;
+}
+
+bool RequestInfoSet::Add(RequestInfoPtr request_info) {
+ DCHECK_OR_RETURN(request_info, false);
+ LOG4CXX_DEBUG(logger_, "Add request app_id = " << request_info->app_id()
+ << "; corr_id = " << request_info->requestId());
+ sync_primitives::AutoLock lock(this_lock_);
+ CheckSetSizes();
+ const std::pair<HashSortedRequestInfoSet::iterator, bool>& insert_resilt =
+ hash_sorted_pending_requests_.insert(request_info);
+ if (insert_resilt.second == true) {
+ const std::pair<TimeSortedRequestInfoSet::iterator, bool>& insert_resilt =
+ time_sorted_pending_requests_.insert(request_info);
+ DCHECK(insert_resilt.second);
+ if (!insert_resilt.second) {
+ return false;
+ }
+ CheckSetSizes();
+ return true;
+ } else {
+ LOG4CXX_ERROR(logger_, "Request with app_id = " << request_info->app_id()
+ << "; corr_id " << request_info->requestId() << " Already exist ");
+ }
+ CheckSetSizes();
+ return false;
+}
+
+RequestInfoPtr RequestInfoSet::Find(const uint32_t connection_key,
+ const uint32_t correlation_id) {
+ RequestInfoPtr result;
+
+ // Request info for searching in request info set by log_n time
+ utils::SharedPtr<FakeRequestInfo> request_info_for_search(
+ new FakeRequestInfo(connection_key, correlation_id));
+
+ sync_primitives::AutoLock lock(this_lock_);
+ HashSortedRequestInfoSet::iterator it =
+ hash_sorted_pending_requests_.find(request_info_for_search);
+ if (it != hash_sorted_pending_requests_.end()) {
+ result = *it;
+ }
+ return result;
+}
+
+RequestInfoPtr RequestInfoSet::Front() {
+ RequestInfoPtr result;
+
+ sync_primitives::AutoLock lock(this_lock_);
+ TimeSortedRequestInfoSet::iterator it = time_sorted_pending_requests_.begin();
+ if (it != time_sorted_pending_requests_.end()) {
+ result = *it;
+ }
+ return result;
+}
+
+RequestInfoPtr RequestInfoSet::FrontWithNotNullTimeout() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ sync_primitives::AutoLock lock(this_lock_);
+ RequestInfoPtr result;
+ TimeSortedRequestInfoSet::iterator it = time_sorted_pending_requests_.begin();
+ while (it != time_sorted_pending_requests_.end()) {
+ RequestInfoPtr tmp = *it;
+ if (0 == tmp ->timeout_sec()) {
+ ++it;
+ } else {
+ result = tmp;
+ it = time_sorted_pending_requests_.end();
+ }
+ }
+ return result;
+}
+
+bool RequestInfoSet::Erase(const RequestInfoPtr request_info) {
+ DCHECK(request_info);
+ if (!request_info) {
+ LOG4CXX_ERROR(logger_, "NULL ponter request_info");
+ return false;
+ }
+ CheckSetSizes();
+
+ size_t erased_count =
+ hash_sorted_pending_requests_.erase(request_info);
+ DCHECK((erased_count <= 1));
+ if (1 == erased_count) {
+ TimeSortedRequestInfoSet::iterator it =
+ time_sorted_pending_requests_.find(request_info);
+ DCHECK(it != time_sorted_pending_requests_.end());
+ if (it == time_sorted_pending_requests_.end()) {
+ LOG4CXX_ERROR(logger_, "Can't find request in time_sorted_requests_");
+ return false;
+ }
+ const RequestInfoPtr found = *it;
+ DCHECK(request_info == found);
+ time_sorted_pending_requests_.erase(it);
+ CheckSetSizes();
+ return 1 == erased_count;
+ }
+ CheckSetSizes();
+ return false;
+}
+
+bool RequestInfoSet::RemoveRequest(const RequestInfoPtr request_info) {
+ sync_primitives::AutoLock lock(this_lock_);
+ return Erase(request_info);
+}
+
+
+uint32_t RequestInfoSet::RemoveRequests(const RequestInfoSet::AppIdCompararator& filter) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ uint32_t erased = 0;
+
+ sync_primitives::AutoLock lock(this_lock_);
+ HashSortedRequestInfoSet::iterator it = std::find_if(
+ hash_sorted_pending_requests_.begin(),
+ hash_sorted_pending_requests_.end(),
+ filter);
+ while (it != hash_sorted_pending_requests_.end()) {
+ HashSortedRequestInfoSet::iterator to_erase = it++;
+ Erase(*to_erase);
+ it = std::find_if(it, hash_sorted_pending_requests_.end(), filter);
+ erased++;
+ }
+ CheckSetSizes();
+ return erased;
+}
+
+
+uint32_t RequestInfoSet::RemoveByConnectionKey(uint32_t connection_key) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return RemoveRequests(AppIdCompararator(AppIdCompararator::Equal, connection_key));
+}
+
+uint32_t RequestInfoSet::RemoveMobileRequests() {
+ LOG4CXX_AUTO_TRACE(logger_);
+ return RemoveRequests(AppIdCompararator(AppIdCompararator::NotEqual, RequestInfo::HmiConnectoinKey));
+}
+
+const size_t RequestInfoSet::Size() {
+ CheckSetSizes();
+ return time_sorted_pending_requests_.size();
+}
+
+void RequestInfoSet::CheckSetSizes() {
+ const ssize_t time_set_size = time_sorted_pending_requests_.size();
+ const ssize_t hash_set_size = hash_sorted_pending_requests_.size();
+ const bool set_sizes_equal = (time_set_size == hash_set_size);
+ DCHECK(set_sizes_equal);
+}
+
+bool RequestInfoSet::CheckTimeScaleMaxRequest(
+ uint32_t app_id,
+ uint32_t app_time_scale,
+ uint32_t max_request_per_time_scale) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (max_request_per_time_scale > 0
+ && app_time_scale > 0) {
+ TimevalStruct end = date_time::DateTime::getCurrentTime();
+ TimevalStruct start = {0, 0};
+ start.tv_sec = end.tv_sec - app_time_scale;
+
+ sync_primitives::AutoLock lock(this_lock_);
+ TimeScale scale(start, end, app_id);
+ const uint32_t count = std::count_if(time_sorted_pending_requests_.begin(),
+ time_sorted_pending_requests_.end(), scale);
+ if (count >= max_request_per_time_scale) {
+ LOG4CXX_WARN(logger_, "Processing requests count " << count <<
+ " exceed application limit " << max_request_per_time_scale);
+ return false;
+ }
+ LOG4CXX_DEBUG(logger_, "Requests count " << count);
+ } else {
+ LOG4CXX_DEBUG(logger_, "CheckTimeScaleMaxRequest disabled");
+ }
+ return true;
+}
+
+bool RequestInfoSet::CheckHMILevelTimeScaleMaxRequest(mobile_apis::HMILevel::eType hmi_level,
+ uint32_t app_id,
+ uint32_t app_time_scale,
+ uint32_t max_request_per_time_scale) {
+ LOG4CXX_AUTO_TRACE(logger_);
+ if (max_request_per_time_scale > 0 &&
+ app_time_scale > 0) {
+ TimevalStruct end = date_time::DateTime::getCurrentTime();
+ TimevalStruct start = {0, 0};
+ start.tv_sec = end.tv_sec - app_time_scale;
+
+ sync_primitives::AutoLock lock(this_lock_);
+ HMILevelTimeScale scale(start, end, app_id, hmi_level);
+ const uint32_t count = std::count_if(time_sorted_pending_requests_.begin(),
+ time_sorted_pending_requests_.end(), scale);
+ if (count >= max_request_per_time_scale) {
+ LOG4CXX_WARN(logger_, "Processing requests count " << count
+ << " exceed application limit " << max_request_per_time_scale
+ << " in hmi level " << hmi_level);
+ return false;
+ }
+ LOG4CXX_DEBUG(logger_, "Requests count " << count);
+ } else {
+ LOG4CXX_DEBUG(logger_, "CheckHMILevelTimeScaleMaxRequest disabled");
+ }
+ return true;
+}
+
+bool RequestInfoSet::AppIdCompararator::operator()(const RequestInfoPtr value_compare) const {
+ switch (compare_type_) {
+ case Equal:
+ return value_compare->app_id() == app_id_;
+ case NotEqual:
+ return value_compare->app_id() != app_id_;
+ default:
+ return false;
+ }
+}
+
+bool RequestInfoTimeComparator::operator()(const RequestInfoPtr lhs,
+ const RequestInfoPtr rhs) const {
+ date_time::TimeCompare compare_result =
+ date_time::DateTime::compareTime(lhs->end_time(), rhs->end_time());
+ if (compare_result == date_time::LESS) {
+ return true;
+ } else if (compare_result == date_time::GREATER) {
+ return false;
+ }
+ // compare_result == date_time::EQUAL
+ // If time is equal, sort by hash
+ return lhs->hash() < rhs->hash();
+}
+
+bool RequestInfoHashComparator::operator()(const RequestInfoPtr lhs,
+ const RequestInfoPtr rhs) const {
+ return lhs->hash() < rhs->hash();
+}
+
+} // namespace request_controller
-} // namespace application_manager
+} // namespace application_manager