prod/native/libcommon/code/transport/HttpEndpoints.h (52 lines of code) (raw):
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you 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.
*/
#pragma once
#include "CommonUtils.h"
#include "CurlSender.h"
#include "HttpEndpoint.h"
#include "LoggerInterface.h"
#include <chrono>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
namespace elasticapm::php::transport {
using namespace std::literals;
class HttpEndpoints {
public:
using endpointUrlHash_t = std::size_t;
HttpEndpoints(std::shared_ptr<LoggerInterface> log) : log_(log) {
}
bool add(std::string endpointUrl, size_t endpointHash, bool verifyServerCertificate, std::string contentType, HttpEndpoint::enpointHeaders_t const &endpointHeaders, std::chrono::milliseconds timeout, std::size_t maxRetries, std::chrono::milliseconds retryDelay) {
std::lock_guard<std::mutex> lock(mutex_);
auto result = endpoints_.try_emplace(endpointHash, std::move(endpointUrl), std::move(contentType), endpointHeaders, maxRetries, retryDelay);
if (connections_.try_emplace(result.first->second.getConnectionId(), log_, timeout, verifyServerCertificate).second) { // CurlSender
ELOGF_DEBUG(log_, TRANSPORT, "HttpEndpoints::add endpointUrl '%s' enpointHash: %X initialize new connectionId: %X", result.first->second.getEndpoint().c_str(), endpointHash, result.first->second.getConnectionId());
return true;
}
return false;
}
std::tuple<std::string, curl_slist *, HttpEndpoint::connectionId_t, CurlSender &, std::size_t, std::chrono::milliseconds> getConnection(size_t endpointHash) {
std::lock_guard<std::mutex> lock(mutex_);
auto const &endpoint = endpoints_.find(endpointHash);
if (endpoint == std::end(endpoints_)) {
std::stringstream stream;
stream << "HttpEnpoints missing enpointHash:" << std::hex << endpointHash;
throw std::runtime_error(stream.str());
}
auto const &connection = connections_.find(endpoint->second.getConnectionId());
if (connection == std::end(connections_)) {
std::stringstream stream;
stream << "HttpEndpoints enpointHash:" << std::hex << endpointHash << " missing connectionId " << std::hex << endpoint->second.getConnectionId();
throw std::runtime_error(stream.str());
}
auto &conn = connection->second;
auto maxRetries = std::max(static_cast<std::size_t>(1), static_cast<std::size_t>(endpoint->second.getMaxRetries()));
auto retryDelay = endpoint->second.getRetryDelay();
return {endpoint->second.getEndpoint(), endpoint->second.getHeaders(), endpoint->second.getConnectionId(), conn, maxRetries, retryDelay};
}
protected:
std::shared_ptr<LoggerInterface> log_;
std::mutex mutex_;
std::unordered_map<endpointUrlHash_t, HttpEndpoint> endpoints_;
std::unordered_map<HttpEndpoint::connectionId_t, CurlSender> connections_;
};
} // namespace elasticapm::php::transport