1bd030d0aSAppaRao Puli /* 2bd030d0aSAppaRao Puli // Copyright (c) 2020 Intel Corporation 3bd030d0aSAppaRao Puli // 4bd030d0aSAppaRao Puli // Licensed under the Apache License, Version 2.0 (the "License"); 5bd030d0aSAppaRao Puli // you may not use this file except in compliance with the License. 6bd030d0aSAppaRao Puli // You may obtain a copy of the License at 7bd030d0aSAppaRao Puli // 8bd030d0aSAppaRao Puli // http://www.apache.org/licenses/LICENSE-2.0 9bd030d0aSAppaRao Puli // 10bd030d0aSAppaRao Puli // Unless required by applicable law or agreed to in writing, software 11bd030d0aSAppaRao Puli // distributed under the License is distributed on an "AS IS" BASIS, 12bd030d0aSAppaRao Puli // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13bd030d0aSAppaRao Puli // See the License for the specific language governing permissions and 14bd030d0aSAppaRao Puli // limitations under the License. 15bd030d0aSAppaRao Puli */ 16bd030d0aSAppaRao Puli #pragma once 1729a82b08SSunitha Harish #include <boost/asio/ip/address.hpp> 1829a82b08SSunitha Harish #include <boost/asio/ip/basic_endpoint.hpp> 19d43cd0caSEd Tanous #include <boost/asio/steady_timer.hpp> 20d43cd0caSEd Tanous #include <boost/beast/core/flat_buffer.hpp> 21d43cd0caSEd Tanous #include <boost/beast/core/tcp_stream.hpp> 22d43cd0caSEd Tanous #include <boost/beast/http/message.hpp> 23bd030d0aSAppaRao Puli #include <boost/beast/version.hpp> 245dfb5b2dSEd Tanous #include <boost/circular_buffer.hpp> 2529a82b08SSunitha Harish #include <include/async_resolve.hpp> 261214b7e7SGunnar Mills 27bd030d0aSAppaRao Puli #include <cstdlib> 28bd030d0aSAppaRao Puli #include <functional> 29bd030d0aSAppaRao Puli #include <iostream> 30bd030d0aSAppaRao Puli #include <memory> 312a5689a7SAppaRao Puli #include <queue> 32bd030d0aSAppaRao Puli #include <string> 33bd030d0aSAppaRao Puli 34bd030d0aSAppaRao Puli namespace crow 35bd030d0aSAppaRao Puli { 36bd030d0aSAppaRao Puli 372a5689a7SAppaRao Puli static constexpr uint8_t maxRequestQueueSize = 50; 387de9f811SSunitha Harish static constexpr unsigned int httpReadBodyLimit = 8192; 392a5689a7SAppaRao Puli 40bd030d0aSAppaRao Puli enum class ConnState 41bd030d0aSAppaRao Puli { 422a5689a7SAppaRao Puli initialized, 4329a82b08SSunitha Harish resolveInProgress, 4429a82b08SSunitha Harish resolveFailed, 452a5689a7SAppaRao Puli connectInProgress, 462a5689a7SAppaRao Puli connectFailed, 47bd030d0aSAppaRao Puli connected, 482a5689a7SAppaRao Puli sendInProgress, 492a5689a7SAppaRao Puli sendFailed, 506eaa1d2fSSunitha Harish recvInProgress, 512a5689a7SAppaRao Puli recvFailed, 522a5689a7SAppaRao Puli idle, 536eaa1d2fSSunitha Harish closeInProgress, 54fe44eb0bSAyushi Smriti closed, 556eaa1d2fSSunitha Harish suspended, 566eaa1d2fSSunitha Harish terminated, 576eaa1d2fSSunitha Harish abortConnection, 586eaa1d2fSSunitha Harish retry 59bd030d0aSAppaRao Puli }; 60bd030d0aSAppaRao Puli 61bd030d0aSAppaRao Puli class HttpClient : public std::enable_shared_from_this<HttpClient> 62bd030d0aSAppaRao Puli { 63bd030d0aSAppaRao Puli private: 6429a82b08SSunitha Harish crow::async_resolve::Resolver resolver; 65bd030d0aSAppaRao Puli boost::beast::tcp_stream conn; 66fe44eb0bSAyushi Smriti boost::asio::steady_timer timer; 677de9f811SSunitha Harish boost::beast::flat_static_buffer<httpReadBodyLimit> buffer; 68bd030d0aSAppaRao Puli boost::beast::http::request<boost::beast::http::string_body> req; 696eaa1d2fSSunitha Harish std::optional< 706eaa1d2fSSunitha Harish boost::beast::http::response_parser<boost::beast::http::string_body>> 716eaa1d2fSSunitha Harish parser; 72116c184bSKrzysztof Grobelny boost::circular_buffer_space_optimized<std::string> requestDataQueue{ 73116c184bSKrzysztof Grobelny maxRequestQueueSize}; 746eaa1d2fSSunitha Harish 7584b35604SEd Tanous ConnState state = ConnState::initialized; 7684b35604SEd Tanous 77fe44eb0bSAyushi Smriti std::string subId; 78bd030d0aSAppaRao Puli std::string host; 79bd030d0aSAppaRao Puli std::string port; 8084b35604SEd Tanous uint32_t retryCount = 0; 8184b35604SEd Tanous uint32_t maxRetryAttempts = 5; 8284b35604SEd Tanous uint32_t retryIntervalSecs = 0; 8384b35604SEd Tanous std::string retryPolicyAction = "TerminateAfterRetries"; 8484b35604SEd Tanous bool runningTimer = false; 85bd030d0aSAppaRao Puli 8629a82b08SSunitha Harish void doResolve() 8729a82b08SSunitha Harish { 8829a82b08SSunitha Harish state = ConnState::resolveInProgress; 8929a82b08SSunitha Harish BMCWEB_LOG_DEBUG << "Trying to resolve: " << host << ":" << port; 9029a82b08SSunitha Harish 9129a82b08SSunitha Harish auto respHandler = 9229a82b08SSunitha Harish [self(shared_from_this())]( 9329a82b08SSunitha Harish const boost::beast::error_code ec, 9429a82b08SSunitha Harish const std::vector<boost::asio::ip::tcp::endpoint>& 9529a82b08SSunitha Harish endpointList) { 9626f6976fSEd Tanous if (ec || (endpointList.empty())) 9729a82b08SSunitha Harish { 9829a82b08SSunitha Harish BMCWEB_LOG_ERROR << "Resolve failed: " << ec.message(); 9929a82b08SSunitha Harish self->state = ConnState::resolveFailed; 1006eaa1d2fSSunitha Harish self->handleConnState(); 10129a82b08SSunitha Harish return; 10229a82b08SSunitha Harish } 10329a82b08SSunitha Harish BMCWEB_LOG_DEBUG << "Resolved"; 10429a82b08SSunitha Harish self->doConnect(endpointList); 10529a82b08SSunitha Harish }; 10629a82b08SSunitha Harish resolver.asyncResolve(host, port, std::move(respHandler)); 10729a82b08SSunitha Harish } 10829a82b08SSunitha Harish 10929a82b08SSunitha Harish void doConnect( 11029a82b08SSunitha Harish const std::vector<boost::asio::ip::tcp::endpoint>& endpointList) 111bd030d0aSAppaRao Puli { 1122a5689a7SAppaRao Puli state = ConnState::connectInProgress; 1132a5689a7SAppaRao Puli 1142a5689a7SAppaRao Puli BMCWEB_LOG_DEBUG << "Trying to connect to: " << host << ":" << port; 115b00dcc27SEd Tanous 11629a82b08SSunitha Harish conn.expires_after(std::chrono::seconds(30)); 11729a82b08SSunitha Harish conn.async_connect( 11829a82b08SSunitha Harish endpointList, [self(shared_from_this())]( 11929a82b08SSunitha Harish const boost::beast::error_code ec, 12029a82b08SSunitha Harish const boost::asio::ip::tcp::endpoint& endpoint) { 1212a5689a7SAppaRao Puli if (ec) 1222a5689a7SAppaRao Puli { 123*8cc8edecSEd Tanous BMCWEB_LOG_ERROR << "Connect " 124*8cc8edecSEd Tanous << endpoint.address().to_string() 1252a5689a7SAppaRao Puli << " failed: " << ec.message(); 1262a5689a7SAppaRao Puli self->state = ConnState::connectFailed; 1276eaa1d2fSSunitha Harish self->handleConnState(); 1282a5689a7SAppaRao Puli return; 1292a5689a7SAppaRao Puli } 130*8cc8edecSEd Tanous BMCWEB_LOG_DEBUG << "Connected to: " 131*8cc8edecSEd Tanous << endpoint.address().to_string(); 1326eaa1d2fSSunitha Harish self->state = ConnState::connected; 1336eaa1d2fSSunitha Harish self->handleConnState(); 1342a5689a7SAppaRao Puli }); 1352a5689a7SAppaRao Puli } 1362a5689a7SAppaRao Puli 1372a5689a7SAppaRao Puli void sendMessage(const std::string& data) 1382a5689a7SAppaRao Puli { 1392a5689a7SAppaRao Puli state = ConnState::sendInProgress; 1402a5689a7SAppaRao Puli 1412a5689a7SAppaRao Puli req.body() = data; 1422a5689a7SAppaRao Puli req.prepare_payload(); 143bd030d0aSAppaRao Puli 144bd030d0aSAppaRao Puli // Set a timeout on the operation 145bd030d0aSAppaRao Puli conn.expires_after(std::chrono::seconds(30)); 146bd030d0aSAppaRao Puli 147bd030d0aSAppaRao Puli // Send the HTTP request to the remote host 148bd030d0aSAppaRao Puli boost::beast::http::async_write( 149bd030d0aSAppaRao Puli conn, req, 1502a5689a7SAppaRao Puli [self(shared_from_this())](const boost::beast::error_code& ec, 151bd030d0aSAppaRao Puli const std::size_t& bytesTransferred) { 152bd030d0aSAppaRao Puli if (ec) 153bd030d0aSAppaRao Puli { 154bd030d0aSAppaRao Puli BMCWEB_LOG_ERROR << "sendMessage() failed: " 155bd030d0aSAppaRao Puli << ec.message(); 1562a5689a7SAppaRao Puli self->state = ConnState::sendFailed; 1576eaa1d2fSSunitha Harish self->handleConnState(); 158bd030d0aSAppaRao Puli return; 159bd030d0aSAppaRao Puli } 160bd030d0aSAppaRao Puli BMCWEB_LOG_DEBUG << "sendMessage() bytes transferred: " 161bd030d0aSAppaRao Puli << bytesTransferred; 162bd030d0aSAppaRao Puli boost::ignore_unused(bytesTransferred); 163bd030d0aSAppaRao Puli 1642a5689a7SAppaRao Puli self->recvMessage(); 165bd030d0aSAppaRao Puli }); 166bd030d0aSAppaRao Puli } 167bd030d0aSAppaRao Puli 168bd030d0aSAppaRao Puli void recvMessage() 169bd030d0aSAppaRao Puli { 1706eaa1d2fSSunitha Harish state = ConnState::recvInProgress; 1716eaa1d2fSSunitha Harish 1726eaa1d2fSSunitha Harish parser.emplace(std::piecewise_construct, std::make_tuple()); 1736eaa1d2fSSunitha Harish parser->body_limit(httpReadBodyLimit); 1746eaa1d2fSSunitha Harish 175bd030d0aSAppaRao Puli // Receive the HTTP response 176bd030d0aSAppaRao Puli boost::beast::http::async_read( 1776eaa1d2fSSunitha Harish conn, buffer, *parser, 1782a5689a7SAppaRao Puli [self(shared_from_this())](const boost::beast::error_code& ec, 179bd030d0aSAppaRao Puli const std::size_t& bytesTransferred) { 180bd030d0aSAppaRao Puli if (ec) 181bd030d0aSAppaRao Puli { 182bd030d0aSAppaRao Puli BMCWEB_LOG_ERROR << "recvMessage() failed: " 183bd030d0aSAppaRao Puli << ec.message(); 1842a5689a7SAppaRao Puli self->state = ConnState::recvFailed; 1856eaa1d2fSSunitha Harish self->handleConnState(); 186bd030d0aSAppaRao Puli return; 187bd030d0aSAppaRao Puli } 188bd030d0aSAppaRao Puli BMCWEB_LOG_DEBUG << "recvMessage() bytes transferred: " 189bd030d0aSAppaRao Puli << bytesTransferred; 1906eaa1d2fSSunitha Harish BMCWEB_LOG_DEBUG << "recvMessage() data: " 191*8cc8edecSEd Tanous << self->parser->get().body(); 192bd030d0aSAppaRao Puli 1936eaa1d2fSSunitha Harish unsigned int respCode = self->parser->get().result_int(); 1946eaa1d2fSSunitha Harish BMCWEB_LOG_DEBUG << "recvMessage() Header Response Code: " 1956eaa1d2fSSunitha Harish << respCode; 1966eaa1d2fSSunitha Harish 1976eaa1d2fSSunitha Harish // 2XX response is considered to be successful 1986eaa1d2fSSunitha Harish if ((respCode < 200) || (respCode >= 300)) 1996eaa1d2fSSunitha Harish { 2006eaa1d2fSSunitha Harish // The listener failed to receive the Sent-Event 2017adb85acSSunitha Harish BMCWEB_LOG_ERROR 2027adb85acSSunitha Harish << "recvMessage() Listener Failed to " 2037adb85acSSunitha Harish "receive Sent-Event. Header Response Code: " 2047adb85acSSunitha Harish << respCode; 2056eaa1d2fSSunitha Harish self->state = ConnState::recvFailed; 2066eaa1d2fSSunitha Harish self->handleConnState(); 2076eaa1d2fSSunitha Harish return; 2086eaa1d2fSSunitha Harish } 209bd030d0aSAppaRao Puli 2102a5689a7SAppaRao Puli // Send is successful, Lets remove data from queue 2112a5689a7SAppaRao Puli // check for next request data in queue. 2127de9f811SSunitha Harish if (!self->requestDataQueue.empty()) 2137de9f811SSunitha Harish { 2147de9f811SSunitha Harish self->requestDataQueue.pop_front(); 2157de9f811SSunitha Harish } 2162a5689a7SAppaRao Puli self->state = ConnState::idle; 2176eaa1d2fSSunitha Harish 2186eaa1d2fSSunitha Harish // Keep the connection alive if server supports it 2196eaa1d2fSSunitha Harish // Else close the connection 2206eaa1d2fSSunitha Harish BMCWEB_LOG_DEBUG << "recvMessage() keepalive : " 2216eaa1d2fSSunitha Harish << self->parser->keep_alive(); 2226eaa1d2fSSunitha Harish if (!self->parser->keep_alive()) 2236eaa1d2fSSunitha Harish { 2246eaa1d2fSSunitha Harish // Abort the connection since server is not keep-alive 2256eaa1d2fSSunitha Harish // enabled 2266eaa1d2fSSunitha Harish self->state = ConnState::abortConnection; 2276eaa1d2fSSunitha Harish } 2286eaa1d2fSSunitha Harish 2296eaa1d2fSSunitha Harish self->handleConnState(); 230bd030d0aSAppaRao Puli }); 231bd030d0aSAppaRao Puli } 232bd030d0aSAppaRao Puli 233bd030d0aSAppaRao Puli void doClose() 234bd030d0aSAppaRao Puli { 2356eaa1d2fSSunitha Harish state = ConnState::closeInProgress; 236bd030d0aSAppaRao Puli boost::beast::error_code ec; 237bd030d0aSAppaRao Puli conn.socket().shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec); 2386eaa1d2fSSunitha Harish conn.close(); 239bd030d0aSAppaRao Puli 240bd030d0aSAppaRao Puli // not_connected happens sometimes so don't bother reporting it. 241bd030d0aSAppaRao Puli if (ec && ec != boost::beast::errc::not_connected) 242bd030d0aSAppaRao Puli { 243bd030d0aSAppaRao Puli BMCWEB_LOG_ERROR << "shutdown failed: " << ec.message(); 244bd030d0aSAppaRao Puli return; 245bd030d0aSAppaRao Puli } 246bd030d0aSAppaRao Puli BMCWEB_LOG_DEBUG << "Connection closed gracefully"; 2476eaa1d2fSSunitha Harish if ((state != ConnState::suspended) && (state != ConnState::terminated)) 2486eaa1d2fSSunitha Harish { 2496eaa1d2fSSunitha Harish state = ConnState::closed; 2506eaa1d2fSSunitha Harish handleConnState(); 2516eaa1d2fSSunitha Harish } 252bd030d0aSAppaRao Puli } 253bd030d0aSAppaRao Puli 2546eaa1d2fSSunitha Harish void waitAndRetry() 255bd030d0aSAppaRao Puli { 2562a5689a7SAppaRao Puli if (retryCount >= maxRetryAttempts) 2572a5689a7SAppaRao Puli { 2586eaa1d2fSSunitha Harish BMCWEB_LOG_ERROR << "Maximum number of retries reached."; 2592a5689a7SAppaRao Puli 2602a5689a7SAppaRao Puli // Clear queue. 2612a5689a7SAppaRao Puli while (!requestDataQueue.empty()) 2622a5689a7SAppaRao Puli { 2637de9f811SSunitha Harish requestDataQueue.pop_front(); 2642a5689a7SAppaRao Puli } 2652a5689a7SAppaRao Puli 2666eaa1d2fSSunitha Harish BMCWEB_LOG_DEBUG << "Retry policy: " << retryPolicyAction; 267fe44eb0bSAyushi Smriti if (retryPolicyAction == "TerminateAfterRetries") 268fe44eb0bSAyushi Smriti { 269fe44eb0bSAyushi Smriti // TODO: delete subscription 270fe44eb0bSAyushi Smriti state = ConnState::terminated; 271fe44eb0bSAyushi Smriti } 2723174e4dfSEd Tanous if (retryPolicyAction == "SuspendRetries") 273fe44eb0bSAyushi Smriti { 2742a5689a7SAppaRao Puli state = ConnState::suspended; 2752a5689a7SAppaRao Puli } 2766eaa1d2fSSunitha Harish // Reset the retrycount to zero so that client can try connecting 2776eaa1d2fSSunitha Harish // again if needed 278fe44eb0bSAyushi Smriti retryCount = 0; 2796eaa1d2fSSunitha Harish handleConnState(); 2802a5689a7SAppaRao Puli return; 2812a5689a7SAppaRao Puli } 2822a5689a7SAppaRao Puli 283fe44eb0bSAyushi Smriti if (runningTimer) 284fe44eb0bSAyushi Smriti { 285fe44eb0bSAyushi Smriti BMCWEB_LOG_DEBUG << "Retry timer is already running."; 286fe44eb0bSAyushi Smriti return; 287fe44eb0bSAyushi Smriti } 288fe44eb0bSAyushi Smriti runningTimer = true; 289fe44eb0bSAyushi Smriti 2902a5689a7SAppaRao Puli retryCount++; 291fe44eb0bSAyushi Smriti 292fe44eb0bSAyushi Smriti BMCWEB_LOG_DEBUG << "Attempt retry after " << retryIntervalSecs 293fe44eb0bSAyushi Smriti << " seconds. RetryCount = " << retryCount; 294fe44eb0bSAyushi Smriti timer.expires_after(std::chrono::seconds(retryIntervalSecs)); 295cb13a392SEd Tanous timer.async_wait( 2966eaa1d2fSSunitha Harish [self = shared_from_this()](const boost::system::error_code ec) { 2976eaa1d2fSSunitha Harish if (ec == boost::asio::error::operation_aborted) 2986eaa1d2fSSunitha Harish { 2996eaa1d2fSSunitha Harish BMCWEB_LOG_DEBUG 3006eaa1d2fSSunitha Harish << "async_wait failed since the operation is aborted" 3016eaa1d2fSSunitha Harish << ec.message(); 3026eaa1d2fSSunitha Harish } 3036eaa1d2fSSunitha Harish else if (ec) 3046eaa1d2fSSunitha Harish { 3056eaa1d2fSSunitha Harish BMCWEB_LOG_ERROR << "async_wait failed: " << ec.message(); 3066eaa1d2fSSunitha Harish // Ignore the error and continue the retry loop to attempt 3076eaa1d2fSSunitha Harish // sending the event as per the retry policy 3086eaa1d2fSSunitha Harish } 309fe44eb0bSAyushi Smriti self->runningTimer = false; 3106eaa1d2fSSunitha Harish 3116eaa1d2fSSunitha Harish // Lets close connection and start from resolve. 3126eaa1d2fSSunitha Harish self->doClose(); 313fe44eb0bSAyushi Smriti }); 3142a5689a7SAppaRao Puli } 3152a5689a7SAppaRao Puli 3166eaa1d2fSSunitha Harish void handleConnState() 317fe44eb0bSAyushi Smriti { 3182a5689a7SAppaRao Puli switch (state) 3192a5689a7SAppaRao Puli { 32029a82b08SSunitha Harish case ConnState::resolveInProgress: 3212a5689a7SAppaRao Puli case ConnState::connectInProgress: 3222a5689a7SAppaRao Puli case ConnState::sendInProgress: 3236eaa1d2fSSunitha Harish case ConnState::recvInProgress: 3246eaa1d2fSSunitha Harish case ConnState::closeInProgress: 3256eaa1d2fSSunitha Harish { 3266eaa1d2fSSunitha Harish BMCWEB_LOG_DEBUG << "Async operation is already in progress"; 3272a5689a7SAppaRao Puli break; 3286eaa1d2fSSunitha Harish } 3292a5689a7SAppaRao Puli case ConnState::initialized: 3302a5689a7SAppaRao Puli case ConnState::closed: 3316eaa1d2fSSunitha Harish { 3326eaa1d2fSSunitha Harish if (requestDataQueue.empty()) 3336eaa1d2fSSunitha Harish { 3346eaa1d2fSSunitha Harish BMCWEB_LOG_DEBUG << "requestDataQueue is empty"; 3356eaa1d2fSSunitha Harish return; 3366eaa1d2fSSunitha Harish } 3376eaa1d2fSSunitha Harish doResolve(); 3386eaa1d2fSSunitha Harish break; 3396eaa1d2fSSunitha Harish } 3406eaa1d2fSSunitha Harish case ConnState::suspended: 3416eaa1d2fSSunitha Harish case ConnState::terminated: 3426eaa1d2fSSunitha Harish { 3436eaa1d2fSSunitha Harish doClose(); 3446eaa1d2fSSunitha Harish break; 3456eaa1d2fSSunitha Harish } 3466eaa1d2fSSunitha Harish case ConnState::resolveFailed: 3472a5689a7SAppaRao Puli case ConnState::connectFailed: 3482a5689a7SAppaRao Puli case ConnState::sendFailed: 34992a74e56SAppaRao Puli case ConnState::recvFailed: 3506eaa1d2fSSunitha Harish case ConnState::retry: 35192a74e56SAppaRao Puli { 3526eaa1d2fSSunitha Harish // In case of failures during connect and handshake 3536eaa1d2fSSunitha Harish // the retry policy will be applied 3546eaa1d2fSSunitha Harish waitAndRetry(); 3552a5689a7SAppaRao Puli break; 3562a5689a7SAppaRao Puli } 3572a5689a7SAppaRao Puli case ConnState::connected: 35892a74e56SAppaRao Puli case ConnState::idle: 35992a74e56SAppaRao Puli { 3606eaa1d2fSSunitha Harish // State idle means, previous attempt is successful 3616eaa1d2fSSunitha Harish // State connected means, client connection is established 3626eaa1d2fSSunitha Harish // successfully 3636eaa1d2fSSunitha Harish if (requestDataQueue.empty()) 3646eaa1d2fSSunitha Harish { 3656eaa1d2fSSunitha Harish BMCWEB_LOG_DEBUG << "requestDataQueue is empty"; 3666eaa1d2fSSunitha Harish return; 3676eaa1d2fSSunitha Harish } 3682a5689a7SAppaRao Puli std::string data = requestDataQueue.front(); 3692a5689a7SAppaRao Puli sendMessage(data); 3702a5689a7SAppaRao Puli break; 3712a5689a7SAppaRao Puli } 3726eaa1d2fSSunitha Harish case ConnState::abortConnection: 3736eaa1d2fSSunitha Harish { 3746eaa1d2fSSunitha Harish // Server did not want to keep alive the session 3756eaa1d2fSSunitha Harish doClose(); 3766eaa1d2fSSunitha Harish break; 3776eaa1d2fSSunitha Harish } 3782a5689a7SAppaRao Puli } 379bd030d0aSAppaRao Puli } 380bd030d0aSAppaRao Puli 381bd030d0aSAppaRao Puli public: 382fe44eb0bSAyushi Smriti explicit HttpClient(boost::asio::io_context& ioc, const std::string& id, 383fe44eb0bSAyushi Smriti const std::string& destIP, const std::string& destPort, 3844da04455SEd Tanous const std::string& destUri, 3854da04455SEd Tanous const boost::beast::http::fields& httpHeader) : 386bd030d0aSAppaRao Puli conn(ioc), 3874da04455SEd Tanous timer(ioc), 3884da04455SEd Tanous req(boost::beast::http::verb::post, destUri, 11, "", httpHeader), 38984b35604SEd Tanous subId(id), host(destIP), port(destPort) 390bd030d0aSAppaRao Puli { 3914da04455SEd Tanous req.set(boost::beast::http::field::host, host); 3924da04455SEd Tanous req.keep_alive(true); 393bd030d0aSAppaRao Puli } 394bd030d0aSAppaRao Puli 3952a5689a7SAppaRao Puli void sendData(const std::string& data) 396bd030d0aSAppaRao Puli { 3976eaa1d2fSSunitha Harish if ((state == ConnState::suspended) || (state == ConnState::terminated)) 398bd030d0aSAppaRao Puli { 399bd030d0aSAppaRao Puli return; 400bd030d0aSAppaRao Puli } 401bd030d0aSAppaRao Puli 4022a5689a7SAppaRao Puli if (requestDataQueue.size() <= maxRequestQueueSize) 4032a5689a7SAppaRao Puli { 4047de9f811SSunitha Harish requestDataQueue.push_back(data); 4056eaa1d2fSSunitha Harish handleConnState(); 4062a5689a7SAppaRao Puli } 4072a5689a7SAppaRao Puli else 4082a5689a7SAppaRao Puli { 4092a5689a7SAppaRao Puli BMCWEB_LOG_ERROR << "Request queue is full. So ignoring data."; 4102a5689a7SAppaRao Puli } 411bd030d0aSAppaRao Puli } 412bd030d0aSAppaRao Puli 413fe44eb0bSAyushi Smriti void setRetryConfig(const uint32_t retryAttempts, 414fe44eb0bSAyushi Smriti const uint32_t retryTimeoutInterval) 415fe44eb0bSAyushi Smriti { 416fe44eb0bSAyushi Smriti maxRetryAttempts = retryAttempts; 417fe44eb0bSAyushi Smriti retryIntervalSecs = retryTimeoutInterval; 418fe44eb0bSAyushi Smriti } 419fe44eb0bSAyushi Smriti 420fe44eb0bSAyushi Smriti void setRetryPolicy(const std::string& retryPolicy) 421fe44eb0bSAyushi Smriti { 422fe44eb0bSAyushi Smriti retryPolicyAction = retryPolicy; 423fe44eb0bSAyushi Smriti } 424bd030d0aSAppaRao Puli }; 425bd030d0aSAppaRao Puli 426bd030d0aSAppaRao Puli } // namespace crow 427