Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions CCDB/include/CCDB/CcdbApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include <string_view>
#include <memory>
#include <map>
#include <curl/curl.h>
#include <TObject.h>
#include <TMessage.h>
#include "CCDB/CcdbObjectInfo.h"
Expand All @@ -37,7 +36,9 @@
class TJAlienCredentials;
#endif

#include "CCDB/CCDBDownloader.h"
// libcurl and the downloader are implementation details of CcdbApi.cxx;
// only opaque handles appear below, so neither header is needed here.
struct curl_slist;

class TFile;
#include <TGrid.h>
Expand All @@ -48,6 +49,7 @@ namespace ccdb
{

class CCDBQuery;
class CCDBDownloader;

/**
* Interface to the CCDB.
Expand All @@ -57,6 +59,9 @@ class CCDBQuery;
* @todo handle errors and exceptions
* @todo extend code coverage
*/
/// stands in for libcurl's `typedef void CURL` without including <curl/curl.h>
using CurlHandle = void;

class CcdbApi //: public DatabaseInterface
{
public:
Expand Down Expand Up @@ -342,7 +347,7 @@ class CcdbApi //: public DatabaseInterface
* @param curl curl handler
* @return
*/
static void curlSetSSLOptions(CURL* curl);
static void curlSetSSLOptions(CurlHandle* curl);

TObject* retrieve(std::string const& path, std::map<std::string, std::string> const& metadata, long timestamp) const;

Expand Down Expand Up @@ -442,7 +447,7 @@ class CcdbApi //: public DatabaseInterface
* @param handle CURL handle associated with the request.
* @param requestCounter Pointer to the variable storing the number of requests to be done.
*/
void asynchPerform(CURL* handle, size_t* requestCounter) const;
void asynchPerform(CurlHandle* handle, size_t* requestCounter) const;

// internal helper function to update a CCDB file with meta information
static void updateMetaInformationInLocalFile(std::string const& filename, std::map<std::string, std::string> const* headers, CCDBQuery const* querysummary = nullptr);
Expand Down Expand Up @@ -478,7 +483,7 @@ class CcdbApi //: public DatabaseInterface
* @param endValidityTimestamp End of validity. If omitted or negative, current timestamp + 1 day is used.
* @return The full url to store an object (url / startValidity / endValidity / [metadata &]* )
*/
std::string getFullUrlForStorage(CURL* curl, const std::string& path, const std::string& objtype,
std::string getFullUrlForStorage(CurlHandle* curl, const std::string& path, const std::string& objtype,
const std::map<std::string, std::string>& metadata,
long startValidityTimestamp = -1, long endValidityTimestamp = -1, int hostIndex = 0) const;

Expand All @@ -489,7 +494,7 @@ class CcdbApi //: public DatabaseInterface
* @param timestamp When the object we retrieve must be valid. If omitted or negative, the current timestamp is used.
* @return The full url to store an object (url / startValidity / endValidity / [metadata &]* )
*/
std::string getFullUrlForRetrieval(CURL* curl, const std::string& path, const std::map<std::string, std::string>& metadata,
std::string getFullUrlForRetrieval(CurlHandle* curl, const std::string& path, const std::map<std::string, std::string>& metadata,
long timestamp = -1, int hostIndex = 0) const;

public:
Expand Down Expand Up @@ -564,25 +569,24 @@ class CcdbApi //: public DatabaseInterface

/// Queries the CCDB server and navigates through possible redirects until binary content is found; Retrieves content as instance
/// given by tinfo if that is possible. Returns nullptr if something fails...
void* navigateURLsAndRetrieveContent(CURL*, std::string const& url, std::type_info const& tinfo, std::map<std::string, std::string>* headers) const;
void* navigateURLsAndRetrieveContent(CurlHandle*, std::string const& url, std::type_info const& tinfo, std::map<std::string, std::string>* headers) const;

// helper that interprets a content chunk as TMemFile and extracts the object therefrom
static void* interpretAsTMemFileAndExtract(char* contentptr, size_t contentsize, std::type_info const& tinfo);

/**
* Initialization of CURL
*/
* Initialization of CurlHandle*/
void curlInit();

// convert type_info to TClass, throw on failure
static TClass* tinfo2TClass(std::type_info const& tinfo);

typedef size_t (*CurlWriteCallback)(void*, size_t, size_t, void*);

void initCurlOptionsForRetrieve(CURL* curlHandle, void* pointer, CurlWriteCallback writeCallback, bool followRedirect = true) const;
void initCurlOptionsForRetrieve(CurlHandle* curlHandle, void* pointer, CurlWriteCallback writeCallback, bool followRedirect = true) const;

/// initialize HTTPS header information for the CURL handle. Needs to be given an existing curl_slist* pointer to work with (may be nullptr), which needs to be free by the caller.
void initCurlHTTPHeaderOptionsForRetrieve(CURL* curlHandle, curl_slist*& option_list, long timestamp, std::map<std::string, std::string>* headers, std::string const& etag, const std::string& createdNotAfter, const std::string& createdNotBefore, std::string_view url) const;
void initCurlHTTPHeaderOptionsForRetrieve(CurlHandle* curlHandle, curl_slist*& option_list, long timestamp, std::map<std::string, std::string>* headers, std::string const& etag, const std::string& createdNotAfter, const std::string& createdNotBefore, std::string_view url) const;

bool receiveToFile(FILE* fileHandle, std::string const& path, std::map<std::string, std::string> const& metadata,
long timestamp, std::map<std::string, std::string>* headers = nullptr, std::string const& etag = "",
Expand Down Expand Up @@ -628,7 +632,7 @@ class CcdbApi //: public DatabaseInterface

// tmp helper and single point of entry for a CURL perform call
// helps to switch between easy handle perform and multi handles in a single place
CURLcode CURL_perform(CURL* handle) const;
int CURL_perform(CurlHandle* handle) const; // returns a CURLcode

mutable CCDBDownloader* mDownloader = nullptr; //! the multi-handle (async) CURL downloader
bool mIsCCDBDownloaderPreferred = false;
Expand Down
58 changes: 30 additions & 28 deletions CCDB/src/CcdbApi.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
///

#include "CCDB/CcdbApi.h"
#include "CCDB/CCDBDownloader.h"
#include <curl/curl.h>
#include "CCDB/CCDBQuery.h"

#include "CommonUtils/StringUtils.h"
Expand Down Expand Up @@ -480,7 +482,7 @@ int CcdbApi::storeAsBinaryFile(const char* buffer, size_t size, const std::strin
}

// Curl preparation
CURL* curl = nullptr;
CurlHandle* curl = nullptr;
curl = curl_easy_init();

// checking that all metadata keys do not contain invalid characters
Expand Down Expand Up @@ -520,7 +522,7 @@ int CcdbApi::storeAsBinaryFile(const char* buffer, size_t size, const std::strin
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);

/* Perform the request, res will get the return code */
res = CURL_perform(curl);
res = static_cast<CURLcode>(CURL_perform(curl));
/* Check for errors */
if (res != CURLE_OK) {
if (res == CURLE_OPERATION_TIMEDOUT) {
Expand Down Expand Up @@ -558,7 +560,7 @@ int CcdbApi::storeAsTFile(const TObject* rootObject, std::string const& path, st
return storeAsBinaryFile(img->data(), img->size(), info.getFileName(), info.getObjectType(), path, metadata, startValidityTimestamp, endValidityTimestamp, maxSize);
}

std::string CcdbApi::getFullUrlForStorage(CURL* curl, const std::string& path, const std::string& objtype,
std::string CcdbApi::getFullUrlForStorage(CurlHandle* curl, const std::string& path, const std::string& objtype,
const std::map<std::string, std::string>& metadata,
long startValidityTimestamp, long endValidityTimestamp, int hostIndex) const
{
Expand Down Expand Up @@ -589,7 +591,7 @@ std::string CcdbApi::getFullUrlForStorage(CURL* curl, const std::string& path, c
}

// todo make a single method of the one above and below
std::string CcdbApi::getFullUrlForRetrieval(CURL* curl, const std::string& path, const std::map<std::string, std::string>& metadata, long timestamp, int hostIndex) const
std::string CcdbApi::getFullUrlForRetrieval(CurlHandle* curl, const std::string& path, const std::map<std::string, std::string>& metadata, long timestamp, int hostIndex) const
{
if (mInSnapshotMode) {
return getSnapshotFile(mSnapshotTopPath, path);
Expand Down Expand Up @@ -674,7 +676,7 @@ static size_t WriteToFileCallback(void* ptr, size_t size, size_t nmemb, FILE* st
* @param parm
* @return
*/
static CURLcode ssl_ctx_callback(CURL*, void*, void* parm)
static CURLcode ssl_ctx_callback(CurlHandle*, void*, void* parm)
{
std::string msg((const char*)parm);
int start = 0, end = msg.find('\n');
Expand All @@ -691,7 +693,7 @@ static CURLcode ssl_ctx_callback(CURL*, void*, void* parm)
return CURLE_OK;
}

void CcdbApi::curlSetSSLOptions(CURL* curl_handle)
void CcdbApi::curlSetSSLOptions(CurlHandle* curl_handle)
{
CredentialsKind cmk = mJAlienCredentials->getPreferedCredentials();

Expand Down Expand Up @@ -719,7 +721,7 @@ void CcdbApi::curlSetSSLOptions(CURL* curl_handle)

using CurlWriteCallback = size_t (*)(void*, size_t, size_t, void*);

void CcdbApi::initCurlOptionsForRetrieve(CURL* curlHandle, void* chunk, CurlWriteCallback writeCallback, bool followRedirect) const
void CcdbApi::initCurlOptionsForRetrieve(CurlHandle* curlHandle, void* chunk, CurlWriteCallback writeCallback, bool followRedirect) const
{
curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, writeCallback);
curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, chunk);
Expand Down Expand Up @@ -774,7 +776,7 @@ size_t header_map_callback(char* buffer, size_t size, size_t nitems, void* userd
}
} // namespace

void CcdbApi::initCurlHTTPHeaderOptionsForRetrieve(CURL* curlHandle, curl_slist*& option_list, long timestamp, std::map<std::string, std::string>* headers, std::string const& etag,
void CcdbApi::initCurlHTTPHeaderOptionsForRetrieve(CurlHandle* curlHandle, curl_slist*& option_list, long timestamp, std::map<std::string, std::string>* headers, std::string const& etag,
const std::string& createdNotAfter, const std::string& createdNotBefore, std::string_view url) const
{
// struct curl_slist* list = nullptr;
Expand Down Expand Up @@ -823,7 +825,7 @@ bool CcdbApi::receiveObject(void* dataHolder, std::string const& path, std::map<
long timestamp, std::map<std::string, std::string>* headers, std::string const& etag,
const std::string& createdNotAfter, const std::string& createdNotBefore, bool followRedirect, CurlWriteCallback writeCallback) const
{
CURL* curlHandle;
CurlHandle* curlHandle;

curlHandle = curl_easy_init();
curl_easy_setopt(curlHandle, CURLOPT_USERAGENT, mUniqueAgentID.c_str());
Expand All @@ -843,7 +845,7 @@ bool CcdbApi::receiveObject(void* dataHolder, std::string const& path, std::map<
curl_slist* option_list = nullptr;
initCurlHTTPHeaderOptionsForRetrieve(curlHandle, option_list, timestamp, headers, etag, createdNotAfter, createdNotBefore, fullUrl);

curlResultCode = CURL_perform(curlHandle);
curlResultCode = static_cast<CURLcode>(CURL_perform(curlHandle));

if (curlResultCode != CURLE_OK) {
LOGP(alarm, "curl_easy_perform() failed: {}", curl_easy_strerror(curlResultCode));
Expand Down Expand Up @@ -1104,7 +1106,7 @@ void* CcdbApi::interpretAsTMemFileAndExtract(char* contentptr, size_t contentsiz
}

// navigate sequence of URLs until TFile content is found; object is extracted and returned
void* CcdbApi::navigateURLsAndRetrieveContent(CURL* curl_handle, std::string const& url, std::type_info const& tinfo, std::map<std::string, std::string>* headers) const
void* CcdbApi::navigateURLsAndRetrieveContent(CurlHandle* curl_handle, std::string const& url, std::type_info const& tinfo, std::map<std::string, std::string>* headers) const
{
// a global internal data structure that can be filled with HTTP header information
// static --> to avoid frequent alloc/dealloc as optimization
Expand All @@ -1131,7 +1133,7 @@ void* CcdbApi::navigateURLsAndRetrieveContent(CURL* curl_handle, std::string con

curlSetSSLOptions(curl_handle);

auto res = CURL_perform(curl_handle);
auto res = static_cast<CURLcode>(CURL_perform(curl_handle));
long response_code = -1;
void* content = nullptr;
bool errorflag = false;
Expand Down Expand Up @@ -1250,7 +1252,7 @@ void* CcdbApi::retrieveFromTFile(std::type_info const& tinfo, std::string const&

// normal mode follows

CURL* curl_handle = curl_easy_init();
CurlHandle* curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, mUniqueAgentID.c_str());
std::string fullUrl = getFullUrlForRetrieval(curl_handle, path, metadata, timestamp); // todo check if function still works correctly in case mInSnapshotMode
// if we are in snapshot mode we can simply open the file; extract the object and return
Expand Down Expand Up @@ -1299,7 +1301,7 @@ size_t CurlWrite_CallbackFunc_StdString2(void* contents, size_t size, size_t nme

std::string CcdbApi::list(std::string const& path, bool latestOnly, std::string const& returnFormat, long createdNotAfter, long createdNotBefore) const
{
CURL* curl;
CurlHandle* curl;
CURLcode res = CURL_LAST;
std::string result;

Expand Down Expand Up @@ -1332,7 +1334,7 @@ std::string CcdbApi::list(std::string const& path, bool latestOnly, std::string
headers = appendGateToken(headers, fullUrl);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

res = CURL_perform(curl);
res = static_cast<CURLcode>(CURL_perform(curl));
if (res != CURLE_OK) {
LOGP(alarm, "CURL_perform() failed: {}", curl_easy_strerror(res));
}
Expand All @@ -1353,7 +1355,7 @@ std::string CcdbApi::getTimestampString(long timestamp) const

void CcdbApi::deleteObject(std::string const& path, long timestamp) const
{
CURL* curl;
CurlHandle* curl;
CURLcode res;
long timestampLocal = timestamp == -1 ? getCurrentTimestamp() : timestamp;

Expand All @@ -1377,7 +1379,7 @@ void CcdbApi::deleteObject(std::string const& path, long timestamp) const
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);

// Perform the request, res will get the return code
res = CURL_perform(curl);
res = static_cast<CURLcode>(CURL_perform(curl));
if (res != CURLE_OK) {
LOGP(alarm, "CURL_perform() failed: {}", curl_easy_strerror(res));
}
Expand All @@ -1391,7 +1393,7 @@ void CcdbApi::deleteObject(std::string const& path, long timestamp) const

void CcdbApi::truncate(std::string const& path) const
{
CURL* curl;
CurlHandle* curl;
CURLcode res;
for (size_t i = 0; i < hostsPool.size(); i++) {
// Declared inside the loop: a stringstream hoisted out of it accumulates,
Expand All @@ -1416,7 +1418,7 @@ void CcdbApi::truncate(std::string const& path) const
curlSetSSLOptions(curl);

// Perform the request, res will get the return code
res = CURL_perform(curl);
res = static_cast<CURLcode>(CURL_perform(curl));
if (res != CURLE_OK) {
LOGP(alarm, "CURL_perform() failed: {}", curl_easy_strerror(res));
}
Expand All @@ -1433,7 +1435,7 @@ size_t write_data(void*, size_t size, size_t nmemb, void*)

bool CcdbApi::isHostReachable() const
{
CURL* curl;
CurlHandle* curl;
CURLcode res = CURL_LAST;
bool result = false;

Expand All @@ -1455,7 +1457,7 @@ bool CcdbApi::isHostReachable() const
curl_easy_setopt(curl, CURLOPT_URL, mUrl.data());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curlSetSSLOptions(curl);
res = CURL_perform(curl);
res = static_cast<CURLcode>(CURL_perform(curl));
result = (res == CURLE_OK);
}

Expand Down Expand Up @@ -1561,7 +1563,7 @@ std::map<std::string, std::string> CcdbApi::retrieveHeaders(std::string const& p
{
// lambda that actually does the call to the CCDB server
auto do_remote_header_call = [this, &path, &metadata, timestamp]() -> std::map<std::string, std::string> {
CURL* curl = curl_easy_init();
CurlHandle* curl = curl_easy_init();
CURLcode res = CURL_LAST;
std::string fullUrl = getFullUrlForRetrieval(curl, path, metadata, timestamp);
std::map<std::string, std::string> headers;
Expand All @@ -1587,7 +1589,7 @@ std::map<std::string, std::string> CcdbApi::retrieveHeaders(std::string const& p
CURLcode getCodeRes = CURL_LAST;
for (size_t hostIndex = 0; hostIndex < hostsPool.size() && (httpCode >= 400 || res > 0 || getCodeRes > 0); hostIndex++) {
curl_easy_setopt(curl, CURLOPT_URL, fullUrl.c_str());
res = CURL_perform(curl);
res = static_cast<CURLcode>(CURL_perform(curl));
if (res != CURLE_OK && res != CURLE_UNSUPPORTED_PROTOCOL) {
// We take out the unsupported protocol error because we are only querying
// header info which is returned in any case. Unsupported protocol error
Expand Down Expand Up @@ -1747,7 +1749,7 @@ TClass* CcdbApi::tinfo2TClass(std::type_info const& tinfo)
int CcdbApi::updateMetadata(std::string const& path, std::map<std::string, std::string> const& metadata, long timestamp, std::string const& id, long newEOV)
{
int ret = -1;
CURL* curl = curl_easy_init();
CurlHandle* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_USERAGENT, mUniqueAgentID.c_str());
if (curl != nullptr) {
CURLcode res;
Expand Down Expand Up @@ -1788,7 +1790,7 @@ int CcdbApi::updateMetadata(std::string const& path, std::map<std::string, std::
curlSetSSLOptions(curl);

// Perform the request, res will get the return code
res = CURL_perform(curl);
res = static_cast<CURLcode>(CURL_perform(curl));
if (res != CURLE_OK) {
LOGP(alarm, "CURL_perform() failed: {}, code: {}", curl_easy_strerror(res), int(res));
ret = int(res);
Expand Down Expand Up @@ -1857,7 +1859,7 @@ void CcdbApi::scheduleDownload(RequestContext& requestContext, size_t* requestCo
return realsize;
};

CURL* curl_handle = curl_easy_init();
CurlHandle* curl_handle = curl_easy_init();
curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, mUniqueAgentID.c_str());
std::string fullUrl = getFullUrlForRetrieval(curl_handle, requestContext.path, requestContext.metadata, requestContext.timestamp);

Expand Down Expand Up @@ -2269,12 +2271,12 @@ void CcdbApi::logReading(const std::string& path, long ts, const std::map<std::s
LOGP(info, "ccdb reads {}{}{} for {} ({}, agent_id: {}), ", mUrl, mUrl.back() == '/' ? "" : "/", upath, ts < 0 ? getCurrentTimestamp() : ts, comment, mUniqueAgentID);
}

void CcdbApi::asynchPerform(CURL* handle, size_t* requestCounter) const
void CcdbApi::asynchPerform(CurlHandle* handle, size_t* requestCounter) const
{
mDownloader->asynchSchedule(handle, requestCounter);
}

CURLcode CcdbApi::CURL_perform(CURL* handle) const
int CcdbApi::CURL_perform(CurlHandle* handle) const
{
if (mIsCCDBDownloaderPreferred) {
return mDownloader->perform(handle);
Expand Down
Loading