From 8c6a23946d6b01b415a9bbf670f8f3245d2de578 Mon Sep 17 00:00:00 2001
From: Mikhail Mineev <Mikhail.Mineev@cern.ch>
Date: Thu, 7 Mar 2024 11:57:03 +0100
Subject: [PATCH 1/6] ctest created

---
 CMakeLists.txt             | 100 +++++++------
 CrestApiLibConfig.cmake.in |  24 ---
 test/CrestApiFs_test.cxx   | 259 ++++++++++++++++++++++++++++++++
 test/CrestApi_test.cxx     | 294 +++++++++++++++++++++++++++++++++++++
 test/test.cxx              |  72 ---------
 5 files changed, 610 insertions(+), 139 deletions(-)
 delete mode 100644 CrestApiLibConfig.cmake.in
 create mode 100644 test/CrestApiFs_test.cxx
 create mode 100644 test/CrestApi_test.cxx
 delete mode 100644 test/test.cxx

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0390a9..b7e2af8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,12 +1,9 @@
 
-# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
 
-# In lxplus you should set the LCG view to the latest version of gcc and cmake
-# source /cvmfs/sft.cern.ch/lcg/views/LCG_104b/x86_64-centos7-gcc11-opt/setup.sh
-# Then use cmake from a build directory : cmake ..
 # Set the name of the package.
-cmake_minimum_required(VERSION 3.10)
-project( CrestApiLib )
+atlas_subdir( CrestApi )
+
 
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -23,7 +20,11 @@ else()
         message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
 endif()
 
+
+# External dependencies.
+find_package(nlohmann_json REQUIRED)
 find_package(CURL REQUIRED)
+find_package( Boost COMPONENTS unit_test_framework regex timer )
 
 if(CURL_FOUND)
     message(STATUS "Found CURL version: ${CURL_VERSION_STRING}")
@@ -49,11 +50,6 @@ SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} ${Boost_INCLUDE_DIR})
 SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} ../build/CrestApi)
 
 
-# External dependencies.
-#find_package( CURL )
-#find_package( Boost )
-
-
 set(header_path "./CrestApi")
 set(HEADERS ${header_path}/CrestApi.h
             ${header_path}/CrestModel.h
@@ -71,36 +67,54 @@ set (SOURCES_EXAMPLE_SRV doc/crest_example_server.cxx)
 set (SOURCES_TEST test/test-json.cxx)
 set (SOURCES_JSON_TEST test/json_parse.cxx)
 
-if(${CMAKE_INSTALL_PREFIX} STREQUAL "/usr/local") 
-    set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/../installed)
-endif()
-
 # Component(s) in the package.
-set(include_dest "${CMAKE_INSTALL_PREFIX}/include/CrestApi")
-
-add_library(CrestApiLib SHARED ${SOURCES} ${HEADERS})
-target_link_libraries(CrestApiLib ${CURL_LIBRARIES} ${Boost_LIBRARIES})
-target_include_directories(CrestApiLib PUBLIC
-                $<BUILD_INTERFACE:${headers_path}> # for headers when building
-                $<INSTALL_INTERFACE:${include_dest}> # for client in install mode
-                )
-install(TARGETS CrestApiLib EXPORT CrestApiLib DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
-install(EXPORT CrestApiLib DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
-
-add_executable(crest_example_server ${SOURCES_EXAMPLE_SRV} ${HEADERS})
-target_link_libraries(crest_example_server CrestApiLib stdc++)
-
-add_executable(crest_example_fs ${SOURCES_EXAMPLE_FS} ${HEADERS})
-target_link_libraries(crest_example_fs CrestApiLib stdc++)
-
-add_executable(test-json ${SOURCES_TEST} ${HEADERS})
-target_link_libraries(test-json CrestApiLib stdc++)
-add_executable(json_parse ${SOURCES_JSON_TEST} ${HEADERS})
-target_link_libraries(json_parse CrestApiLib stdc++)
-
-# Generate the Config.cmake file
-configure_file(CrestApiLibConfig.cmake.in CrestApiLibConfig.cmake @ONLY)
-
-install(FILES ${HEADERS} DESTINATION "${include_dest}")
-install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CrestApiLibConfig.cmake"
-        DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/CrestApiLib")
\ No newline at end of file
+atlas_add_library( CrestApiLib
+   ${HEADERS} ${SOURCES}
+   PUBLIC_HEADERS CrestApi
+   LINK_LIBRARIES nlohmann_json::nlohmann_json
+   PRIVATE_INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
+   PRIVATE_LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+
+# The CrestApi examples for the CREST server.
+atlas_add_executable(crest_example_server
+   SOURCES ${SOURCES_EXAMPLE_SRV} ${HEADERS}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+
+# The CrestApi examples for the file storage.
+atlas_add_executable(crest_example_fs 
+   SOURCES ${SOURCES_EXAMPLE_FS} ${HEADERS}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+
+# The CrestApi test.
+atlas_add_executable(test-json 
+   SOURCES ${SOURCES_TEST} ${HEADERS}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+
+ # The CrestApi test.
+atlas_add_executable(json_parse
+   SOURCES ${SOURCES_JSON_TEST} ${HEADERS}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+ 
+# CrestApi package test for the file storage methods (CrestApiFs.cxx).
+atlas_add_test( CrestApiFs_test
+   SOURCES test/CrestApiFs_test.cxx ${HEADERS} ${SOURCES}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++
+   POST_EXEC_SCRIPT nopost.sh )
+
+# CrestApi package test for the server methods (CrestApi.cxx).
+atlas_add_test( CrestApi_test
+   SOURCES test/CrestApi_test.cxx ${HEADERS} ${SOURCES}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++
+   POST_EXEC_SCRIPT nopost.sh )
diff --git a/CrestApiLibConfig.cmake.in b/CrestApiLibConfig.cmake.in
deleted file mode 100644
index 7e38c81..0000000
--- a/CrestApiLibConfig.cmake.in
+++ /dev/null
@@ -1,24 +0,0 @@
-# - Check if the user provided a path to CrestApiLib_INCLUDE_DIRS.
-#   If not, set it to the correct include directory.
-if(NOT CrestApiLib_INCLUDE_DIRS)
-    set(CrestApiLib_INCLUDE_DIRS "@CrestApiLib_INSTALL_PREFIX@/include")
-endif()
-
-# Create a CrestApiLib::CrestApiLib target to be used by consumers of CrestApiLib
-add_library(CrestApiLib::CrestApiLib INTERFACE IMPORTED)
-set_target_properties(CrestApiLib::CrestApiLib PROPERTIES
-    INTERFACE_INCLUDE_DIRECTORIES "${CrestApiLib_INCLUDE_DIRS}"
-)
-
-# Set variables to help consumers locate CrestApiLib library and headers
-set(CrestApiLib_FOUND TRUE)
-set(CrestApiLib_INCLUDE_DIRS "${CrestApiLib_INCLUDE_DIRS}")
-set(CrestApiLib_LIBRARIES CrestApiLib::CrestApiLib)
-
-# Provide configuration results
-include(CMakeFindDependencyMacro)
-if(NOT TARGET CURL::CURL) # This condition is optional and can be modified based on your dependencies
-    find_dependency(CURL REQUIRED)
-endif()
-
-include("${CMAKE_CURRENT_LIST_DIR}/../../CrestApiLib.cmake")
diff --git a/test/CrestApiFs_test.cxx b/test/CrestApiFs_test.cxx
new file mode 100644
index 0000000..41e13a4
--- /dev/null
+++ b/test/CrestApiFs_test.cxx
@@ -0,0 +1,259 @@
+
+/**
+ * @file CrestApi/test/CrestApiFs_test.cxx
+ * @brief Some tests for file storage methods. 
+ */
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MAIN
+#define BOOST_TEST_MODULE TEST_CRESTAPI
+
+#include <boost/test/unit_test.hpp>
+
+#include "../CrestApi/CrestApiFs.h"
+#include <string>
+
+using namespace Crest;
+
+BOOST_AUTO_TEST_SUITE(CrestApiFsTest)
+
+  std::string workdir = "/tmp/crest";
+  CrestFsClient myCrestClient = CrestFsClient(true, workdir);
+  std::string tagname = "test_tag_01";
+  std::string global_tag = "TEST_GLOBAL_TAG_01";
+
+
+  BOOST_AUTO_TEST_CASE(tag_test){
+    std::cout << "\n====== CrestApi Test for the file storage methods =====\n\n";
+    
+
+    std::cout << std::endl << "1) Tag test" << std::endl;    
+
+    nlohmann::json js =
+      {
+          {"description", "none"},
+          {"endOfValidity", 0},
+          {"insertionTime", "2018-12-06T11:18:35.641+0000"},
+          {"lastValidatedTime", 0},
+          {"modificationTime", "2018-12-06T11:18:35.641+0000"},
+          {"name", tagname},
+          {"payloadSpec", "Json2Cool"},
+          {"synchronization", "none"},
+          {"timeType", "time"}
+      };
+
+    std::cout << "tag (" << tagname << ") =" << std::endl
+              << js.dump(4) << std::endl;
+    
+    TagDto dto = TagDto();
+    dto = dto.from_json(js);
+
+    try
+    {
+      myCrestClient.createTag(dto);
+      std::cout << "Tag " << tagname 
+                << " created in the directory " << workdir
+		<< "." << std::endl;
+    } 
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot create the tag " << tagname
+                << " in the directory" << workdir << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    TagDto dto2;
+
+    std::cout << "Reading the file from the file storage..." << std::endl;
+    
+    try
+    {
+      dto2 = myCrestClient.findTag(tagname);
+      std::cout << std::endl
+                << "tag (" << tagname << ") = " << std::endl
+                << dto2.to_json().dump(4) << std::endl;
+    }
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot get the tag " << tagname
+                << " from the directory" << workdir << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    // create the patch
+    nlohmann::json js2 = dto2.to_json();
+    js.erase("insertionTime");
+    js2.erase("insertionTime");
+    js.erase("modificationTime");
+    js2.erase("modificationTime");
+    nlohmann::json patch = nlohmann::json::diff(js, js2);
+
+    bool res = patch.empty();
+    if (res) {
+      std::cout << "Tag test passed successfully." << std::endl;
+    }
+    else {
+      std::cout << "Tag test failed." << std::endl;
+    }
+
+    BOOST_TEST(res);
+  }
+
+  BOOST_AUTO_TEST_CASE(tag_meta_test){
+
+    std::cout << std::endl << "2) Tag meta info test" << std::endl;   
+
+    nlohmann::json channel = {{"0", "ATLAS_PREFERRED"}};
+    nlohmann::json chanList = nlohmann::json::array({channel});
+
+    nlohmann::json tagInfo =
+      {
+          {"channel_list", chanList},
+          {"node_description", "description of the node"},
+          {"payload_spec", "stave:Int32, eta:Int32, mag:Float, base:Float, free:Float"}};
+
+    nlohmann::json js =
+      {
+          {"tagName", tagname},
+          {"description", "none"},
+          {"chansize", 1},
+          {"colsize", 6},
+          {"tagInfo", tagInfo.dump()},
+          {"insertionTime", "2020-12-04"}};
+
+    std::cout << "tag meta (" << tagname << ") =" << std::endl
+              << js.dump(4) << std::endl;
+
+    TagMetaDto dto = TagMetaDto();
+    dto = dto.from_json(js);
+
+    try
+    {
+      myCrestClient.createTagMeta(dto);
+      std::cout << "Tag meta info for tag " << tagname 
+                << " created in the directory " << workdir
+		<< "." << std::endl;
+    } 
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot create the tag meta info for tag " << tagname
+                << " in the directory" << workdir << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    TagMetaDto dto2;
+
+    std::cout << "Reading the tag meta from the file storage..." << std::endl;
+    
+    try
+    {
+      dto2 = myCrestClient.findTagMeta(tagname);
+      std::cout << std::endl
+                << "tag meta (" << tagname << ") = " << std::endl
+                << dto2.to_json().dump(4) << std::endl;
+    }
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot get the tag meta " << tagname
+                << " from the directory" << workdir << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    // create the patch
+    nlohmann::json js2 = dto2.to_json();
+    js.erase("insertionTime");
+    js2.erase("insertionTime");
+    nlohmann::json patch = nlohmann::json::diff(js, js2);
+
+    bool res = patch.empty();
+    if (res) {
+      std::cout << "Tag meta info test passed successfully." << std::endl;
+    }
+    else {
+      std::cout << "Tag meta info test failed." << std::endl;
+    }
+
+    BOOST_TEST(res);
+  }
+
+
+  BOOST_AUTO_TEST_CASE(global_tag_test){
+
+    std::cout << std::endl << "3) Global Tag test" << std::endl;    
+
+    nlohmann::json js =
+    {
+      {"name", global_tag},
+      {"validity", 0.0},
+      {"description", "test"},
+      {"release", "1"},
+      {"insertionTime", "2018-12-18T11:32:58.081+0000"},
+      {"snapshotTime", "2018-12-18T11:32:58+0000"},
+      {"scenario", "test"},
+      {"workflow", "M"},
+      {"type", "t"},
+    };
+
+    std::cout << "global tag (" << global_tag << ") =" << std::endl
+              << js.dump(4) << std::endl;
+
+    GlobalTagDto dto = GlobalTagDto();
+    dto = dto.from_json(js);
+
+    try
+    {
+      myCrestClient.createGlobalTag(dto);
+      std::cout << "Global tag " << global_tag 
+                << " created on the CREST server. " << std::endl;
+    } 
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot create the global tag " << global_tag
+                << " on CREST server." << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    GlobalTagDto dto2;
+
+    std::cout << "Reading the global tag from the CREST server..." << std::endl;
+    
+    try
+    {
+      dto2 = myCrestClient.findGlobalTag(global_tag);
+      std::cout << std::endl
+                << "global tag (" << global_tag << ") = " << std::endl
+                << dto2.to_json().dump(4) << std::endl;
+    }
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot get the global tag " << global_tag
+                << " from the CREST server." << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    // create the patch
+    nlohmann::json js2 = dto2.to_json();
+    js.erase("insertionTime");
+    js2.erase("insertionTime");
+    js.erase("modificationTime");
+    js2.erase("modificationTime");
+    js2.erase("insertionTimeMilli");
+    js2.erase("snapshotTimeMilli");
+    nlohmann::json patch = nlohmann::json::diff(js, js2);
+    std::cout << "global tag patch = " << std:: endl
+	      << patch.dump(4) << std::endl;
+
+    bool res = patch.empty();
+    if (res) {
+      std::cout << "The global tag test passed successfully." << std::endl;
+    }
+    else {
+      std::cout << "The global tag test failed." << std::endl;
+    }
+
+    BOOST_TEST(res);
+  }
+
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/CrestApi_test.cxx b/test/CrestApi_test.cxx
new file mode 100644
index 0000000..eacc41b
--- /dev/null
+++ b/test/CrestApi_test.cxx
@@ -0,0 +1,294 @@
+
+/**
+ * @file CrestApi/test/CrestApi_test.cxx
+ * @brief Some tests for server methods. 
+ */
+
+#define BOOST_TEST_DYN_LINK
+#define BOOST_TEST_MAIN
+#define BOOST_TEST_MODULE TEST_CRESTAPI
+
+#include <boost/test/unit_test.hpp>
+
+#include "../CrestApi/CrestApi.h"
+#include <string>
+
+using namespace Crest;
+
+BOOST_AUTO_TEST_SUITE(CrestApiTest)
+
+  std::string crest_server = "http://crest-undertow-api.web.cern.ch:80/api-v4.0";
+  CrestClient myCrestClient = CrestClient(crest_server,false);
+  std::string tagname = "test_tag_01";
+  std::string global_tag = "TEST_GLOBAL_TAG_01";
+
+
+  BOOST_AUTO_TEST_CASE(tag_test){
+    std::cout << "\n====== CrestApi Test for the server methods =====\n";
+    std::cout << "CREST server:  " << crest_server << "\n\n";
+    
+
+    std::cout << std::endl << "1) Tag test" << std::endl;    
+
+    nlohmann::json js =
+      {
+          {"description", "none"},
+          {"endOfValidity", 0},
+          {"insertionTime", "2018-12-06T11:18:35.641+0000"},
+          {"lastValidatedTime", 0},
+          {"modificationTime", "2018-12-06T11:18:35.641+0000"},
+          {"name", tagname},
+          {"payloadSpec", "Json2Cool"},
+          {"synchronization", "none"},
+          {"timeType", "time"}
+      };
+
+    std::cout << "tag (" << tagname << ") =" << std::endl
+              << js.dump(4) << std::endl;
+    
+    TagDto dto = TagDto();
+    dto = dto.from_json(js);
+
+    try
+    {
+      myCrestClient.createTag(dto);
+      std::cout << "Tag " << tagname 
+                << " created on the CREST server. " << std::endl;
+    } 
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot create the tag " << tagname
+                << " on CREST server." << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    TagDto dto2;
+
+    std::cout << "Reading the file from the CREST server..." << std::endl;
+    
+    try
+    {
+      dto2 = myCrestClient.findTag(tagname);
+      std::cout << std::endl
+                << "tag (" << tagname << ") = " << std::endl
+                << dto2.to_json().dump(4) << std::endl;
+    }
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot get the tag " << tagname
+                << " from the CREST server." << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    // create the patch
+    nlohmann::json js2 = dto2.to_json();
+    js.erase("insertionTime");
+    js2.erase("insertionTime");
+    js.erase("modificationTime");
+    js2.erase("modificationTime");
+    nlohmann::json patch = nlohmann::json::diff(js, js2);
+
+    bool res = patch.empty();
+    if (res) {
+      std::cout << "Tag test passed successfully." << std::endl;
+    }
+    else {
+      std::cout << "Tag test failed." << std::endl;
+    }
+
+    BOOST_TEST(res);
+  }
+
+  BOOST_AUTO_TEST_CASE(tag_meta_test){
+
+    std::cout << std::endl << "2) Tag meta info test" << std::endl;   
+
+    nlohmann::json channel = {{"0", "ATLAS_PREFERRED"}};
+    nlohmann::json chanList = nlohmann::json::array({channel});
+
+    nlohmann::json tagInfo =
+      {
+          {"channel_list", chanList},
+          {"node_description", "description of the node"},
+          {"payload_spec", "stave:Int32, eta:Int32, mag:Float, base:Float, free:Float"}};
+
+    nlohmann::json js =
+      {
+          {"tagName", tagname},
+          {"description", "none"},
+          {"chansize", 1},
+          {"colsize", 6},
+          {"tagInfo", tagInfo.dump()},
+          {"insertionTime", "2018-12-06T11:18:35.641+0000"}
+      };
+
+    std::cout << "tag meta (" << tagname << ") =" << std::endl
+              << js.dump(4) << std::endl;
+
+    TagMetaDto dto = TagMetaDto();
+    dto = dto.from_json(js);
+
+    try
+    {
+      myCrestClient.createTagMeta(dto);
+      std::cout << "Tag meta info for tag " << tagname 
+                << " created on the CREST server."
+		<< std::endl;
+    } 
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot create the tag meta info for tag " << tagname
+                << " on the CREST server" << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    TagMetaDto dto2;
+
+    std::cout << "Reading the tag meta from the CREST server..." << std::endl;
+    
+    try
+    {
+      dto2 = myCrestClient.findTagMeta(tagname);
+      std::cout << std::endl
+                << "tag meta (" << tagname << ") = " << std::endl
+                << dto2.to_json().dump(4) << std::endl;
+    }
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot get the tag meta " << tagname
+                << " from the CREST server." << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    // create the patch
+    nlohmann::json js2 = dto2.to_json();
+    js.erase("insertionTime");
+    js2.erase("insertionTime");
+    nlohmann::json patch = nlohmann::json::diff(js, js2);
+
+    bool res = patch.empty();
+    if (res) {
+      std::cout << "Tag meta info test passed successfully." << std::endl;
+    }
+    else {
+      std::cout << "Tag meta info test failed." << std::endl;
+    }
+
+    BOOST_TEST(res);
+  }
+
+  BOOST_AUTO_TEST_CASE(global_tag_test){
+
+    std::cout << std::endl << "3) Global Tag test" << std::endl;    
+
+    nlohmann::json js =
+    {
+      {"name", global_tag},
+      {"validity", 0.0},
+      {"description", "test"},
+      {"release", "1"},
+      {"insertionTime", "2018-12-18T11:32:58.081+0000"},
+      {"snapshotTime", "2018-12-18T11:32:58+0000"},
+      {"scenario", "test"},
+      {"workflow", "M"},
+      {"type", "t"},
+    };
+
+    std::cout << "global tag (" << global_tag << ") =" << std::endl
+              << js.dump(4) << std::endl;
+
+    GlobalTagDto dto = GlobalTagDto();
+    dto = dto.from_json(js);
+
+    try
+    {
+      myCrestClient.createGlobalTag(dto);
+      std::cout << "Global tag " << global_tag 
+                << " created on the CREST server. " << std::endl;
+    } 
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot create the global tag " << global_tag
+                << " on CREST server." << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    GlobalTagDto dto2;
+
+    std::cout << "Reading the global tag from the CREST server..." << std::endl;
+    
+    try
+    {
+      dto2 = myCrestClient.findGlobalTag(global_tag);
+      std::cout << std::endl
+                << "global tag (" << global_tag << ") = " << std::endl
+                << dto2.to_json().dump(4) << std::endl;
+    }
+    catch (const std::exception &e)
+    {
+      std::cout << "Error: Cannot get the global tag " << global_tag
+                << " from the CREST server." << std::endl;
+      std::cout << e.what() << std::endl;
+    }
+
+    // create the patch
+    nlohmann::json js2 = dto2.to_json();
+    js.erase("insertionTime");
+    js2.erase("insertionTime");
+    js.erase("modificationTime");
+    js2.erase("modificationTime");
+    js2.erase("insertionTimeMilli");
+    js2.erase("snapshotTimeMilli");
+    nlohmann::json patch = nlohmann::json::diff(js, js2);
+    std::cout << "global tag patch = " << std:: endl
+	      << patch.dump(4) << std::endl;
+
+    bool res = patch.empty();
+    if (res) {
+      std::cout << "The global tag test passed successfully." << std::endl;
+    }
+    else {
+      std::cout << "The global tag test failed." << std::endl;
+    }
+
+    BOOST_TEST(res);
+  }
+
+
+  BOOST_AUTO_TEST_CASE(global_tag_removing_test){
+
+    std::cout << std::endl << "4) Global tag removing test" << std::endl;    
+    bool res = true;
+
+    try{
+      myCrestClient.removeGlobalTag(global_tag);
+      std::cout << "The global tag " << global_tag << " was removed from CREST server." << std::endl;
+    }
+    catch (const std::runtime_error& e) {
+      std::cout << "The global tag " << global_tag << " was not removed from server." << std::endl;
+      res = false;
+    }
+
+    BOOST_TEST(res);
+  }
+
+
+  BOOST_AUTO_TEST_CASE(tag_removing_test){
+
+    std::cout << std::endl << "5) Tag removing test" << std::endl;    
+    bool res = true;
+
+    try{
+      myCrestClient.removeTag(tagname);
+      std::cout << "The tag " << tagname << " was removed from CREST server." << std::endl;
+    }
+    catch (const std::runtime_error& e) {
+      std::cout << "Tag " << tagname << " was not removed from server." << std::endl;
+      res = false;
+    }
+
+    BOOST_TEST(res);
+  }
+
+BOOST_AUTO_TEST_SUITE_END()
+
diff --git a/test/test.cxx b/test/test.cxx
deleted file mode 100644
index 2b46909..0000000
--- a/test/test.cxx
+++ /dev/null
@@ -1,72 +0,0 @@
-#include <cassert>
-#include <iostream>
-
-#include <nlohmann/json.hpp>
-
-#include <CrestApi/CrestApi.h>
-#include <filesystem>
-
-using namespace Crest;
-
-int main() {
-  std::cout << "CREST Client Libtary test 2" << std::endl;
-
-  int retv = 0;
-
-  // CrestApi Library innitialization for local data storage:
-
-  
-  //std::string work_dir = "/tmp/crest_dump";
-  std::string work_dir=std::filesystem::current_path();
-  bool rewrite = true;
-  CrestClient testCrestClient = CrestClient(rewrite, work_dir); // CrestClient();
-
-  //==============================================
-  // Tag Creation
-
-  std::cout << std::endl << "test: createTag" << std::endl;
-
-  // Tag description as a JSON:
-
-  nlohmann::json js =
-  {
-    {"description", "none"},
-    {"endOfValidity", 0},
-    {"insertionTime", "2018-12-06T11:18:35.641+0000"},
-    {"lastValidatedTime", 0},
-    {"modificationTime", "2018-12-06T11:18:35.641+0000"},
-    {"name", "test_MvG3a"},
-    {"payloadSpec", "stave: Int32, eta: Int32, mag: Float, base: Float, free: Float"},
-    {"synchronization", "none"},
-    {"timeType", "time"}
-  };
-
-  try{
-    testCrestClient.createTag(js);
-    std::cout << std::endl << "test: createTag (success)" << std::endl;
-  }
-  catch (const std::runtime_error& e) {
-    std::cout << std::endl << "test: createTag (failed)" << std::endl;
-    retv = 1;
-  }
-
-
-  //==============================================
-  // Tag Reading
-
-  std::cout << std::endl << "test: findTag" << std::endl;
-  std::string tagname = "test_MvG3a";
-
-  try {
-    nlohmann::json tag_info = testCrestClient.findTag(tagname);
-    std::cout << std::endl << "test: findTag (result)" << std::endl
-              << tag_info.dump(4) << std::endl;
-  }
-  catch (const std::runtime_error& e) {
-    std::cout << std::endl << "test: findTag (failed)" << std::endl;
-    retv = 1;
-  }
-  //
-
-  return retv;
-}
-- 
GitLab


From b69bb76a7a0112e1d0929e6aabf370e443d7578b Mon Sep 17 00:00:00 2001
From: Mikhail Mineev <Mikhail.Mineev@cern.ch>
Date: Wed, 13 Mar 2024 18:21:04 +0100
Subject: [PATCH 2/6] parameters renamed and printings removed

---
 CrestApi/CrestApi.h          |   7 +-
 CrestApi/CrestRequest.h      |   2 +-
 doc/crest_example_fs.cxx     |  13 +--
 doc/crest_example_server.cxx |  19 ++++-
 src/CrestApi.cxx             | 161 +++++++++--------------------------
 src/CrestRequest.cxx         |   2 +-
 6 files changed, 71 insertions(+), 133 deletions(-)

diff --git a/CrestApi/CrestApi.h b/CrestApi/CrestApi.h
index 352e219..ac0b4f9 100644
--- a/CrestApi/CrestApi.h
+++ b/CrestApi/CrestApi.h
@@ -76,19 +76,18 @@ namespace Crest
 
         std::string m_host;
         std::string m_port;
-        std::string currentTag;
 
-        Crest::CrestRequest request = Crest::CrestRequest();
+        Crest::CrestRequest m_request = Crest::CrestRequest();
 
         nlohmann::json getMgmtInfo();
         std::string getClientVersion();
         std::string getCrestVersion();
         int getMajorVersion(std::string &str);
         nlohmann::json getJson(const std::string &str, const char *method) const;
-        int checkErrors(const nlohmann::json &js, const char *method) const;
+      //int checkErrors(const nlohmann::json &js, const char *method) const;
         std::string parseXMLOutput(const std::string_view xmlBuffer) const;
         std::string removeCR(const std::string &str) const;
-        void checkResult(CURLcode res, long response_code, const std::string &st, const char *method_name);
+      //void checkResult(CURLcode res, long response_code, const std::string &st, const char *method_name);
 
     public:
         CrestClient(const std::string &host, const std::string &port, bool checkVersion = false);
diff --git a/CrestApi/CrestRequest.h b/CrestApi/CrestRequest.h
index d951e9f..8c54c5f 100644
--- a/CrestApi/CrestRequest.h
+++ b/CrestApi/CrestRequest.h
@@ -75,7 +75,7 @@ namespace Crest
         std::string make_url(const std::string &address) const;
 
         char* m_CREST_PROXY = NULL;
-        const char* s_CREST_PROXY_VAR = "SOCKS_PROXY";
+        const char* m_CREST_PROXY_VAR = "SOCKS_PROXY";
 
         // Auxiliary method to make request to the CREST Server. This method is used by other methods realizing the
         // requests with the concrete kinds of data (iovs|payloads|tags…).
diff --git a/doc/crest_example_fs.cxx b/doc/crest_example_fs.cxx
index 824b63a..d2b87c2 100644
--- a/doc/crest_example_fs.cxx
+++ b/doc/crest_example_fs.cxx
@@ -917,31 +917,32 @@ int main(int argc, char *argv[])
   //
   // tag method tests for file storage
   testCreateTag_FS(tagname);
+  testCreateTagMeta_FS(tagname);
+  testFindTagMeta_FS(tagname);
   testFindTag_FS(tagname);
   //
 
-  //
+  /*
   testCreateGlobalTagMap_FS(globaltag,tagname);
   testFindGlobalTagMap_FS(globaltag);
-  //  
+  */  
 
-  //
+  /*
   // tag meta info method tests for file storage
   testCreateTag_FS(tagname);
   testFindTag_FS(tagname);
   testStorePayloads_FS(tagname);
   testGetSize_FS(tagname);
-  //
+  */
 
   /*
   testCreateTag_FS(tagname);
   testStorePayloadsFile_FS(tagname);
   testGetPayload_FS("abdc424af89446400ba4b31ace71538b05eab779449f35cfa3e4a00d9bf53c1b");
   testGetPayloadMeta_FS("abdc424af89446400ba4b31ace71538b05eab779449f35cfa3e4a00d9bf53c1b");
-  */
 
   testListIovs_FS(tagname);
-
+  */
 
   // testNameList_FS(); // private method
 
diff --git a/doc/crest_example_server.cxx b/doc/crest_example_server.cxx
index 3fe8ce0..3f3f248 100644
--- a/doc/crest_example_server.cxx
+++ b/doc/crest_example_server.cxx
@@ -3,7 +3,7 @@
    \brief Main file
 
    This file contains the examples for the CREST C++ Client Library.
-   Main part of the examples is commented. Pl testCreateGlobalTagMapFsease uncomment the code you need.
+   Main part of the examples is commented. Please uncomment the code you need.
    Check and correct (if it is necessary) the CREST Server parameters in CrestClient instances.
  */
 
@@ -423,6 +423,22 @@ int createFile(std::string filePath) {
     return 0;
 }
 
+void testGetSize(const std::string& tagname) {
+  std::cout << std::endl << "test: getSize" << std::endl;
+  // CrestFsClient myCrestClient = CrestFsClient(true, "/tmp/crest");
+  CrestClient myCrestClient = CrestClient(SURL,false);
+
+  try {
+    int info = myCrestClient.getSize(tagname);
+    std::cout << std::endl << "test: getSize (result) = "
+              << info << std::endl;
+  }
+  catch (const std::exception& e) {
+    std::cout << std::endl << "test: getSize (failed)" << std::endl;
+    std::cout << e.what() << std::endl;
+  }
+}
+
 int main(int argc, char* argv[]) {
   if (argc == 2) {
     SURL = argv[1];
@@ -458,6 +474,7 @@ int main(int argc, char* argv[]) {
     testGetPayload(tagname);
     testRemoveMap(globaltagname, tagname);
     testRemoveGlobalTag(globaltagname);
+    testGetSize(tagname);
     testRemoveTag(tagname);
     
 
diff --git a/src/CrestApi.cxx b/src/CrestApi.cxx
index 7b3edd8..a22764f 100644
--- a/src/CrestApi.cxx
+++ b/src/CrestApi.cxx
@@ -35,8 +35,8 @@ namespace Crest
         {
             checkCrestVersion();
         }
-        request.setHost(m_host);
-        request.setPort(m_port);
+        m_request.setHost(m_host);
+        m_request.setPort(m_port);
     }
 
     /**
@@ -94,8 +94,8 @@ namespace Crest
 
         m_port = std::string(port);
         m_host = std::string(host);
-        request.setHost(m_host);
-        request.setPort(m_port);
+        m_request.setHost(m_host);
+        m_request.setPort(m_port);
 
         if (check_version == true)
         {
@@ -109,6 +109,7 @@ namespace Crest
      */
     CrestClient::~CrestClient() {}
 
+  
     // The auxillary method to remove XML/HTML tags from a std::string
     std::string CrestClient::parseXMLOutput(const std::string_view xmlBuffer) const
     {
@@ -136,6 +137,7 @@ namespace Crest
         return plainString;
     }
 
+ 
     // The auxillary method to remove carridge returns from a std::string
     std::string CrestClient::removeCR(const std::string &str) const
     {
@@ -150,87 +152,6 @@ namespace Crest
         return str2;
     }
 
-    void CrestClient::checkResult(CURLcode res, const long response_code, const std::string &st,
-                                  const char *method_name)
-    {
-        // Bad HTTP response:
-
-        if (res != CURLE_OK)
-        {
-            std::string mes = "ERROR in ";
-            mes += method_name;
-            mes += " | ";
-            throw std::runtime_error(mes + std::to_string(response_code));
-        }
-
-        // Errors, decoded from JSON CREST Server messages:
-        try
-        {
-            nlohmann::json js = nlohmann::json::parse(st);
-            nlohmann::json respond = getJson(st, method_name);
-            checkErrors(respond, method_name);
-        }
-        catch (nlohmann::json::parse_error &e)
-        {
-            std::string mes = "ERROR in ";
-            mes += method_name;
-            mes += " | ";
-        }
-
-        // HTTP response code error interval:
-
-        if (response_code >= 400 || response_code == 303)
-        {
-            std::string s = parseXMLOutput(st); // to remove HTML tags
-            s = removeCR(s);                    // to remove end lines and carridge returns
-            std::string mes = "ERROR in ";
-            mes += method_name;
-            mes += " | ";
-            throw std::runtime_error(mes + "CREST Server response : " + s);
-        }
-    }
-
-    // Verify Errors in the CREST Server response:
-    int CrestClient::checkErrors(const nlohmann::json &js, const char *method) const
-    {
-        int result = 0;
-        auto res = js.find("type");
-
-        // Old format parsing:
-
-        if (res != js.end())
-        {
-            std::string type = js.value("type", " unknown type ");
-            if (type == "error" || type == "info")
-            {
-                std::string message = js.value("message", " unknown message ");
-                throw std::runtime_error("ERROR in " + std::string(method) + " | CREST response: " + message);
-            }
-        }
-
-        // New format parsing:
-
-        auto r1 = js.find("error");
-        auto r2 = js.find("message");
-
-        if (r1 != js.end())
-        {
-            std::string error = js.value("error", " unknown error ");
-            if (r2 != js.end())
-            {
-                std::string message = js.value("message", "");
-                if (message == "")
-                {
-                    throw std::runtime_error("ERROR in " + std::string(method) + " | CREST response: " + error);
-                }
-                else
-                {
-                    throw std::runtime_error("ERROR in " + std::string(method) + " | CREST response: " + message);
-                }
-            }
-        }
-        return result;
-    }
 
     /**
      * CrestClient::getJson method is used to convert the string to the json object.
@@ -276,7 +197,7 @@ namespace Crest
         std::string retv;
         nlohmann::json js = nullptr;
 
-        retv = request.performRequest(current_path, GET, js, method_name);
+        retv = m_request.performRequest(current_path, GET, js, method_name);
 
         nlohmann::json respond = getJson(retv, method_name);
 
@@ -285,7 +206,6 @@ namespace Crest
 
     std::string CrestClient::getCrestVersion()
     {
-        const char *method_name = "getCrestVersion";
 
         std::string version = "";
         nlohmann::json buildInfo;
@@ -366,7 +286,7 @@ namespace Crest
         current_path += s_GLOBALTAG_PATH;
         std::string retv;
         nlohmann::json js = dto.to_json();
-        retv = request.performRequest(current_path, POST, js, method_name);
+        retv = m_request.performRequest(current_path, POST, js, method_name);
     }
 
     GlobalTagDto CrestClient::findGlobalTag(const std::string &name)
@@ -380,7 +300,7 @@ namespace Crest
         std::string retv;
 
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
+        retv = m_request.performRequest(current_path, GET, js, method_name);
         nlohmann::json response = getJson(retv, method_name);
 
         GlobalTagSetDto dto = GlobalTagSetDto::from_json(response);
@@ -423,7 +343,7 @@ namespace Crest
         std::string retv;
 
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
+        retv = m_request.performRequest(current_path, GET, js, method_name);
         nlohmann::json response = getJson(retv, method_name);
 
         GlobalTagSetDto dto = GlobalTagSetDto::from_json(response);
@@ -443,7 +363,7 @@ namespace Crest
         current_path += name;
         std::string retv;
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, DELETE, js, method_name);
+        retv = m_request.performRequest(current_path, DELETE, js, method_name);
     }
 
     //==============================================================================================================
@@ -456,8 +376,8 @@ namespace Crest
         current_path += s_TAG_PATH;
         std::string retv;
         nlohmann::json js = dto.to_json();
-        retv = request.performRequest(current_path, POST, js, method_name);
-        std::cout << "CrestClient::createTag: retv = " << retv << std::endl;
+        retv = m_request.performRequest(current_path, POST, js, method_name);
+        // std::cout << "CrestClient::createTag: retv = " << retv << std::endl;
     }
 
     // The method to find a tag:
@@ -471,7 +391,7 @@ namespace Crest
         current_path += name;
         std::string retv;
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
+        retv = m_request.performRequest(current_path, GET, js, method_name);
         nlohmann::json response = getJson(retv, method_name);
         TagSetDto dto = TagSetDto::from_json(response);
 
@@ -514,7 +434,7 @@ namespace Crest
         std::string retv;
 
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
+        retv = m_request.performRequest(current_path, GET, js, method_name);
         nlohmann::json response = getJson(retv, method_name);
 
         TagSetDto dto = TagSetDto::from_json(response);
@@ -534,7 +454,7 @@ namespace Crest
         current_path += name;
         std::string retv;
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, DELETE, js, method_name);
+        retv = m_request.performRequest(current_path, DELETE, js, method_name);
     }
 
     //==============================================================================================================
@@ -551,8 +471,8 @@ namespace Crest
 
         std::string retv;
         nlohmann::json js = dto.to_json();
-        retv = request.performRequest(current_path, POST, js, method_name);
-        std::cout << "CrestClient::createTagMeta: retv = " << retv << std::endl;
+        retv = m_request.performRequest(current_path, POST, js, method_name);
+        // std::cout << "CrestClient::createTagMeta: retv = " << retv << std::endl;
     }
 
     void CrestClient::updateTagMeta(TagMetaDto &dto)
@@ -567,8 +487,8 @@ namespace Crest
 
         std::string retv;
         nlohmann::json js = dto.to_json();
-        retv = request.performRequest(current_path, PUT, js, method_name);
-        std::cout << "CrestClient::updateTagMeta: retv = " << retv << std::endl;
+        retv = m_request.performRequest(current_path, PUT, js, method_name);
+        // std::cout << "CrestClient::updateTagMeta: retv = " << retv << std::endl;
     }
 
     TagMetaDto CrestClient::findTagMeta(const std::string &name)
@@ -582,7 +502,7 @@ namespace Crest
         current_path += s_META_PATH;
         std::string retv;
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
+        retv = m_request.performRequest(current_path, GET, js, method_name);
         nlohmann::json response = getJson(retv, method_name);
 
         TagMetaSetDto dto = TagMetaSetDto::from_json(response);
@@ -605,9 +525,11 @@ namespace Crest
         std::string retv;
 
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
+        retv = m_request.performRequest(current_path, GET, js, method_name);
         nlohmann::json respond = getJson(retv, method_name);
 
+	// std::cout << "respond = " << std::endl  << respond.dump(4) << std::endl;
+
         auto res = respond.find("resources");
         nlohmann::json r;
 
@@ -639,8 +561,8 @@ namespace Crest
         current_path += s_GLOBALTAG_MAP_PATH;
         std::string retv;
         nlohmann::json js = dto.to_json();
-        retv = request.performRequest(current_path, POST, js, method_name);
-        std::cout << "CrestClient::createGlobalTagMap: retv = " << retv << std::endl;
+        retv = m_request.performRequest(current_path, POST, js, method_name);
+        // std::cout << "CrestClient::createGlobalTagMap: retv = " << retv << std::endl;
     }
 
     GlobalTagMapSetDto CrestClient::findGlobalTagMap(const std::string &name, const std::string &xCrestMapMode)
@@ -665,8 +587,8 @@ namespace Crest
         }
         std::string retv;
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name, headers_params);
-        std::cout << "CrestClient::findGlobalTagMap: retv = " << retv << std::endl;
+        retv = m_request.performRequest(current_path, GET, js, method_name, headers_params);
+        // std::cout << "CrestClient::findGlobalTagMap: retv = " << retv << std::endl;
         nlohmann::json response = getJson(retv, method_name);
         GlobalTagMapSetDto dto = GlobalTagMapSetDto::from_json(response);
 
@@ -703,7 +625,7 @@ namespace Crest
 
         std::string retv;
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, DELETE, js, method_name);
+        retv = m_request.performRequest(current_path, DELETE, js, method_name);
     }
 
     //==============================================================================================================
@@ -737,7 +659,7 @@ namespace Crest
         std::string retv;
 
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
+        retv = m_request.performRequest(current_path, GET, js, method_name);
         nlohmann::json response = getJson(retv, method_name);
 
         IovSetDto dto = IovSetDto::from_json(response);
@@ -762,7 +684,7 @@ namespace Crest
         std::string retv;
 
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
+        retv = m_request.performRequest(current_path, GET, js, method_name);
         nlohmann::json response = getJson(retv, method_name);
 
         IovSetDto dto = IovSetDto::from_json(response);
@@ -780,7 +702,6 @@ namespace Crest
                                 const std::string &version,
                                 double endTime)
     {
-        const char *method_name = "CrestClient::storeData";
 
         std::string current_path = m_PATH;
         current_path += s_PAYLOAD_PATH;
@@ -789,12 +710,12 @@ namespace Crest
         nlohmann::json js = storeSetJson.to_json();
         if (payloadFormat == "JSON")
         {
-            std::cout << "Store payload as JSON " << js.dump(4) << std::endl;
-            retv = request.uploadPayload(current_path, PUT, tag, endTime, js, objectType, compressionType, version, files);
+	    // std::cout << "Store payload as JSON " << js.dump(4) << std::endl;
+            retv = m_request.uploadPayload(current_path, PUT, tag, endTime, js, objectType, compressionType, version, files);
         }
         else
         {
-            std::cout << "Store payload as FILE " << js.dump(4) << std::endl;
+	    // std::cout << "Store payload as FILE " << js.dump(4) << std::endl;
             // Assumes the data content in the JSON is just a file path.
             nlohmann::json resources = nullptr;
 
@@ -809,7 +730,7 @@ namespace Crest
                 nlohmann::json element = resources[i];
                 std::string file_param;
 
-                std::cout << "Load part " << i << " for element " << element.dump(4) << std::endl;
+                // std::cout << "Load part " << i << " for element " << element.dump(4) << std::endl;
 
                 auto subjectIdIter1 = element.find("data");
                 if (subjectIdIter1 != element.end())
@@ -822,9 +743,9 @@ namespace Crest
                 std::string data_file = file_param.substr(found_dots + 3, word_size);
                 files.push_back(data_file);
             }
-            retv = request.uploadPayload(current_path, POST, tag, endTime, js, objectType, compressionType, version, files);
+            retv = m_request.uploadPayload(current_path, POST, tag, endTime, js, objectType, compressionType, version, files);
         }
-        std::cout << "CrestClient::storeData: retv = " << retv << std::endl;
+        // std::cout << "CrestClient::storeData: retv = " << retv << std::endl;
     }
 
     std::string CrestClient::getPayload(const std::string &hash)
@@ -838,8 +759,8 @@ namespace Crest
         current_path += "?format=BLOB";
         std::string retv;
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
-        std::cout << "CrestClient::getPayload: retv = " << retv << std::endl;
+        retv = m_request.performRequest(current_path, GET, js, method_name);
+        // std::cout << "CrestClient::getPayload: retv = " << retv << std::endl;
         return retv;
     }
 
@@ -854,8 +775,8 @@ namespace Crest
         current_path += "?format=META";
         std::string retv;
         nlohmann::json js = nullptr;
-        retv = request.performRequest(current_path, GET, js, method_name);
-        std::cout << "CrestClient::getPayloadMeta: retv = " << retv << std::endl;
+        retv = m_request.performRequest(current_path, GET, js, method_name);
+        // std::cout << "CrestClient::getPayloadMeta: retv = " << retv << std::endl;
         nlohmann::json response = getJson(retv, method_name);
 
         PayloadSetDto dto = PayloadSetDto::from_json(response);
diff --git a/src/CrestRequest.cxx b/src/CrestRequest.cxx
index e0c6bb5..8923eee 100644
--- a/src/CrestRequest.cxx
+++ b/src/CrestRequest.cxx
@@ -19,7 +19,7 @@ namespace Crest
   CrestRequest::CrestRequest()
   {
     curl_global_init(CURL_GLOBAL_ALL);
-    m_CREST_PROXY = std::getenv("SOCKS_PROXY");
+    m_CREST_PROXY = std::getenv(m_CREST_PROXY_VAR);
   }
 
   CrestRequest::~CrestRequest()
-- 
GitLab


From 988c1248ae70742db83bc4f71e5405bc6391839b Mon Sep 17 00:00:00 2001
From: Mikhail Mineev <Mikhail.Mineev@cern.ch>
Date: Fri, 15 Mar 2024 11:10:53 +0100
Subject: [PATCH 3/6] error handling in request methods and exception

---
 CMakeLists.txt               |  1 +
 CrestApi/CrestApi.h          |  3 +-
 CrestApi/CrestException.h    | 17 ++++++++++
 CrestApi/CrestModel.h        |  3 +-
 doc/crest_example_server.cxx |  6 ++--
 src/CrestApi.cxx             | 35 ++++++++++++++++-----
 src/CrestApiFs.cxx           | 50 +++++++++++++++---------------
 src/CrestRequest.cxx         | 60 ++++++++++++++++--------------------
 test/CrestApi_test.cxx       |  4 +--
 9 files changed, 105 insertions(+), 74 deletions(-)
 create mode 100644 CrestApi/CrestException.h

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b7e2af8..9836388 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,6 +56,7 @@ set(HEADERS ${header_path}/CrestApi.h
             ${header_path}/CrestApiBase.h
             ${header_path}/CrestApiFs.h
             ${header_path}/CrestRequest.h
+	    ${header_path}/CrestException.h
 		    ${header_path}/CrestApiExt.h
 		    ${header_path}/picosha2.h)
 
diff --git a/CrestApi/CrestApi.h b/CrestApi/CrestApi.h
index ac0b4f9..43ad825 100644
--- a/CrestApi/CrestApi.h
+++ b/CrestApi/CrestApi.h
@@ -84,10 +84,9 @@ namespace Crest
         std::string getCrestVersion();
         int getMajorVersion(std::string &str);
         nlohmann::json getJson(const std::string &str, const char *method) const;
-      //int checkErrors(const nlohmann::json &js, const char *method) const;
         std::string parseXMLOutput(const std::string_view xmlBuffer) const;
         std::string removeCR(const std::string &str) const;
-      //void checkResult(CURLcode res, long response_code, const std::string &st, const char *method_name);
+
 
     public:
         CrestClient(const std::string &host, const std::string &port, bool checkVersion = false);
diff --git a/CrestApi/CrestException.h b/CrestApi/CrestException.h
new file mode 100644
index 0000000..8d3e162
--- /dev/null
+++ b/CrestApi/CrestException.h
@@ -0,0 +1,17 @@
+namespace Crest
+{
+
+  class CrestException : public std::runtime_error
+  {
+  public:
+    CrestException(const std::string& what = "") : std::runtime_error(what) {}
+  };
+
+
+  class CrestConflictException : public CrestException
+  {
+  public:
+    CrestConflictException(const std::string& what = "") : CrestException(what) {}
+  };
+
+}
diff --git a/CrestApi/CrestModel.h b/CrestApi/CrestModel.h
index f343917..f7a8804 100644
--- a/CrestApi/CrestModel.h
+++ b/CrestApi/CrestModel.h
@@ -7,6 +7,7 @@
 #include <vector>
 #include <optional>
 #include "nlohmann/json.hpp"
+#include <CrestApi/CrestException.h>
 
 #include <optional>
 
@@ -254,7 +255,7 @@ public:
         }
         else
         {
-            throw std::runtime_error("ERROR in TagDto.from_json: JSON contains no tag name.");
+	  throw Crest::CrestException("ERROR in TagDto.from_json: JSON contains no tag name.");
         }
 
         tag.timeType = j.value("timeType", "");
diff --git a/doc/crest_example_server.cxx b/doc/crest_example_server.cxx
index 3f3f248..fbdc1f3 100644
--- a/doc/crest_example_server.cxx
+++ b/doc/crest_example_server.cxx
@@ -130,7 +130,7 @@ void testRemoveGlobalTag(const std::string& tagname) {
     myCrestClient.removeGlobalTag(tagname);
     std::cout << std::endl << "test: removeGlobalTag (success)" << std::endl;
   }
-  catch (const std::runtime_error& e) {
+  catch (const CrestException& e) {
     std::cout << std::endl << "test: removeGlobalTag (failed)" << std::endl;
   }
 }
@@ -213,7 +213,7 @@ void testRemoveTag(const std::string& tagname) {
     myCrestClient.removeTag(tagname);
     std::cout << std::endl << "test: removeTag (success)" << std::endl;
   }
-  catch (const std::runtime_error& e) {
+  catch (const CrestException& e) {
     std::cout << std::endl << "test: removeTag (failed)" << std::endl;
   }
 }
@@ -271,7 +271,7 @@ void testRemoveMap(const std::string& globaltagname, const std::string& tagname)
     myCrestClient.removeGlobalTagMap(globaltagname, "None", "/MYFOLDER", tagname);
     std::cout << std::endl << "test: removeMap (success)" << std::endl;
   }
-  catch (const std::runtime_error& e) {
+  catch (const CrestException& e) {
     std::cout << std::endl << "test: removeMap (failed)" << std::endl;
   }
 }
diff --git a/src/CrestApi.cxx b/src/CrestApi.cxx
index a22764f..c736bd1 100644
--- a/src/CrestApi.cxx
+++ b/src/CrestApi.cxx
@@ -2,6 +2,7 @@
 #include <CrestApi/CrestApi.h>
 #include <CrestApi/CrestRequest.h>
 #include <CrestApi/CrestModel.h>
+// #include <CrestApi/CrestException.h>
 
 #include <boost/uuid/uuid.hpp>            // uuid class
 #include <boost/uuid/uuid_generators.hpp> // generators
@@ -173,18 +174,18 @@ namespace Crest
                 // method name is undefined
 
                 std::string wh = e.what();
-                throw std::runtime_error("ERROR in JSON conversion: " + wh + " | In string: " + str);
+                throw CrestException("ERROR in JSON conversion: " + wh + " | In string: " + str);
             }
             else
             {
                 std::string str2 = parseXMLOutput(str); // to remove HTML tags use this function
                 std::string str3 = removeCR(str2);      // to remove carridge return
-                throw std::runtime_error("ERROR in " + std::string(method) + " | CREST Server response : " + str3);
+                throw CrestException("ERROR in " + std::string(method) + " | CREST Server response : " + str3);
             }
         }
         catch (const std::exception &e)
         {
-            throw std::runtime_error("ERROR in CrestClient::" + (std::string)method + ": " + e.what());
+            throw CrestException("ERROR in CrestClient::" + (std::string)method + ": " + e.what());
         }
         return js;
     }
@@ -219,7 +220,7 @@ namespace Crest
         }
         catch (const std::exception &e)
         {
-            throw std::runtime_error("ERROR in CrestClient::getCrestVersion: " + to_string(info) + " does not contain version info.");
+            throw CrestException("ERROR in CrestClient::getCrestVersion: " + to_string(info) + " does not contain version info.");
         }
         return version;
     }
@@ -236,7 +237,7 @@ namespace Crest
 
         if (n < 1)
         {
-            throw std::runtime_error("ERROR in CrestClient::getMajorVersion: string \"" + str + "\" does not contain major version.");
+            throw CrestException("ERROR in CrestClient::getMajorVersion: string \"" + str + "\" does not contain major version.");
         }
 
         std::string vers = str.substr(0, n);
@@ -247,7 +248,7 @@ namespace Crest
         }
         catch (const std::exception &e)
         {
-            throw std::runtime_error("ERROR in CrestClient::getMajorVersion: string \"" + str + "\" does not contain major version.");
+            throw CrestException("ERROR in CrestClient::getMajorVersion: string \"" + str + "\" does not contain major version.");
         }
 
         return v;
@@ -263,7 +264,7 @@ namespace Crest
 
         if (clientVersion != serverVersion)
         {
-            throw std::runtime_error("ERROR in CrestClient::checkCrestVersion: CrestApi version \"" + client + "\" does not correspond to the server version \"" + server + "\".");
+	  throw CrestException("ERROR in CrestClient::checkCrestVersion: CrestApi version \"" + client + "\" does not correspond to the server version \"" + server + "\".");
         }
     }
 
@@ -545,7 +546,7 @@ namespace Crest
         }
         else
         {
-            throw std::runtime_error("ERROR in CrestClient::getSize CREST Server JSON response has no \"size\" key.");
+            throw CrestException("ERROR in CrestClient::getSize CREST Server JSON response has no \"size\" key.");
         }
 
         return result;
@@ -655,6 +656,14 @@ namespace Crest
         }
         current_path += "&snapshot=";
         current_path += std::to_string(snapshot);
+	//
+        current_path += "&size=";
+        current_path += std::to_string(size);
+        current_path += "&page=";
+        current_path += std::to_string(page);
+        current_path += "&sort=";
+        current_path += sort;
+	//
 
         std::string retv;
 
@@ -681,6 +690,16 @@ namespace Crest
         current_path += name;
         current_path += "&snapshot=";
         current_path += std::to_string(snapshot);
+
+	//
+        current_path += "&size=";
+        current_path += std::to_string(size);
+        current_path += "&page=";
+        current_path += std::to_string(page);
+        current_path += "&sort=";
+        current_path += sort;
+	//
+	
         std::string retv;
 
         nlohmann::json js = nullptr;
diff --git a/src/CrestApiFs.cxx b/src/CrestApiFs.cxx
index 95de266..968eefa 100644
--- a/src/CrestApiFs.cxx
+++ b/src/CrestApiFs.cxx
@@ -107,7 +107,7 @@ namespace Crest
     }
     else
     {
-      throw std::runtime_error("ERROR in CrestFsClient::createGlobalTag: global tag name is not set.");
+      throw CrestException("ERROR in CrestFsClient::createGlobalTag: global tag name is not set.");
     }
 
     std::string workDir = buildPath(s_FS_GLOBALTAG_PATH, name);
@@ -146,7 +146,7 @@ namespace Crest
     }
     catch (...)
     {
-      throw std::runtime_error(
+      throw CrestException(
           "ERROR in CrestFsClient::findGlobalTag: cannot get the global tag " + name + " form the file storage.");
     }
 
@@ -171,7 +171,7 @@ namespace Crest
     if (sort == "name:ASC")       ascending = true;
     else if (sort == "name:DESC")  ascending = false;
     else {
-      throw std::runtime_error(
+      throw CrestException(
 		"ERROR in CrestFsClient::listTags: wrong sort parameter." + sort);
     }
 
@@ -206,7 +206,7 @@ namespace Crest
       tagSet.format = "TagSetDto";
     }
     catch (const std::exception& e) {
-      throw std::runtime_error(
+      throw CrestException(
 		"ERROR in CrestFsClient::listGlobalTags: cannot get the tag list.");
     }
 
@@ -265,7 +265,7 @@ namespace Crest
     }
     catch (...)
     {
-      throw std::runtime_error(
+      throw CrestException(
           "ERROR in CrestFsClient::findTag: cannot get the tag " + name + " form the file storage.");
     }
 
@@ -289,7 +289,7 @@ namespace Crest
     if (sort == "name:ASC")       ascending = true;
     else if (sort == "name:DESC")  ascending = false;
     else {
-      throw std::runtime_error(
+      throw CrestException(
 		"ERROR in CrestFsClient::listTags: wrong sort parameter." + sort);
     }
 
@@ -324,7 +324,7 @@ namespace Crest
       tagSet.format = "TagSetDto";
     }
     catch (const std::exception& e) {
-      throw std::runtime_error(
+      throw CrestException(
 		"ERROR in CrestFsClient::listTags: cannot get the tag list.");
     }
 
@@ -395,7 +395,7 @@ namespace Crest
     }
     catch (...)
     {
-      throw std::runtime_error(
+      throw CrestException(
           "ERROR in CrestFsClient::findTagMeta: cannot get the tag " + name + " form the file storage.");
     }
 
@@ -416,7 +416,7 @@ namespace Crest
     }
     catch (...)
     {
-      throw std::runtime_error("ERROR in CrestClient::createGlobalTagMap: cannot get the global tag name from JSON.");
+      throw CrestException("ERROR in CrestClient::createGlobalTagMap: cannot get the global tag name from JSON.");
     }
 
     // tag name:
@@ -427,7 +427,7 @@ namespace Crest
     }
     catch (...)
     {
-      throw std::runtime_error("ERROR in CrestClient::createGlobalTagMap: cannot get the tag name from JSON.");
+      throw CrestException("ERROR in CrestClient::createGlobalTagMap: cannot get the tag name from JSON.");
     }
 
     std::string workDir = buildPath(s_FS_GLOBALTAG_PATH, name);
@@ -446,7 +446,7 @@ namespace Crest
       }
       catch (...)
       {
-        throw std::runtime_error("ERROR in CrestFsClient::createGlobalTagMap: global tag map file corrupted.");
+        throw CrestException("ERROR in CrestFsClient::createGlobalTagMap: global tag map file corrupted.");
       }
 
       if (std::filesystem::exists(std::filesystem::path(catalogFile)))
@@ -499,7 +499,7 @@ namespace Crest
 
   void CrestFsClient::checkFsException(const char *method_name)
   {
-    throw std::runtime_error("ERROR in " + std::string(method_name) + " This methods is unsupported for FILESYSTEM mode");
+    throw CrestException("ERROR in " + std::string(method_name) + " This methods is unsupported for FILESYSTEM mode");
   }
 
  
@@ -508,7 +508,7 @@ namespace Crest
     nlohmann::json js = nullptr;
 
     if(xCrestMapMode != "Trace"){
-      throw std::runtime_error(
+      throw CrestException(
               "ERROR in CrestFsClient::getGlobalTagMap: not supported value for the parameter xCrestMapMode = " + xCrestMapMode);
     }
 
@@ -523,7 +523,7 @@ namespace Crest
       js = nlohmann::json::parse(tag);
     }
     catch (...) {
-      throw std::runtime_error(
+      throw CrestException(
               "ERROR in CrestFsClient::getGlobalTagMap: cannot get the global tag map " + name +
               " form the file storage.");
     }
@@ -568,14 +568,14 @@ namespace Crest
 
     }
     catch (...) {
-      throw std::runtime_error("ERROR in CrestClient::selectIovsFS : cannot get the iov list form file storage");
+      throw CrestException("ERROR in CrestClient::selectIovsFS : cannot get the iov list form file storage");
     }
 
     bool ascending = true;
     if (sort == "id.since:ASC")        ascending = true;
     else if (sort == "id.since:DESC")  ascending = false;
     else {
-      throw std::runtime_error(
+      throw CrestException(
 		"ERROR in CrestFsClient::selectIovs: wrong sort parameter." + sort);
     }
 
@@ -604,7 +604,7 @@ namespace Crest
     }
     catch (const std::exception& e)
     {
-      throw std::runtime_error("ERROR in CrestFsClient::findAllIovs : cannot get the iov information form file storage "); // MvG
+      throw CrestException("ERROR in CrestFsClient::findAllIovs : cannot get the iov information form file storage "); // MvG
     }
 
     return js;
@@ -674,7 +674,7 @@ namespace Crest
     } // end of try
     catch (...)
     {
-      throw std::runtime_error("ERROR in CrestFsClient::storeData cannot store the data in a file");
+      throw CrestException("ERROR in CrestFsClient::storeData cannot store the data in a file");
     } // end of catch
     flush();
   }
@@ -756,7 +756,7 @@ namespace Crest
         std::filesystem::copy_file(payloadLocalFile, tagFile);
       }
       catch (std::filesystem::filesystem_error& e){
-	throw std::runtime_error("ERROR in CrestFsClient::storePayloadDump cannot not save payload file: " + tagFile  + e.what());
+	throw CrestException("ERROR in CrestFsClient::storePayloadDump cannot not save payload file: " + tagFile  + e.what());
       }
     }
 
@@ -798,7 +798,7 @@ namespace Crest
         }
         catch (...)
         {
-          throw std::runtime_error(
+          throw CrestException(
               "ERROR in CrestFsClient::storePayloadDump cannot get data for tag \"" + tag + "\" from file storage.");
         }
       }
@@ -826,7 +826,7 @@ namespace Crest
     std::ifstream ifs(file);
     if (!ifs)
     {
-      throw std::runtime_error(
+      throw CrestException(
           "ERROR in CrestFsClient::getHashForFile cannot open file \"" + file + "\".");
     }
 
@@ -862,12 +862,12 @@ namespace Crest
         res = getFileString(filePath);
       }
       else {
-	throw std::runtime_error("payload with hash " + hash + " does not exist.");
+	throw CrestException("payload with hash " + hash + " does not exist.");
       }
     }
     catch (const std::exception& e) {
       std::string message = e.what();
-      throw std::runtime_error("ERROR in CrestFsClient::getPayload cannot get the payload form file storage, " + message);
+      throw CrestException("ERROR in CrestFsClient::getPayload cannot get the payload form file storage, " + message);
     }
 
     return res;
@@ -896,12 +896,12 @@ namespace Crest
         dto = PayloadDto::from_json(js);
       }
       else {
-	throw std::runtime_error("payload meta info with hash " + hash + " does not exist.");
+	throw CrestException("payload meta info with hash " + hash + " does not exist.");
       }
     }
     catch (const std::exception& e) {
       std::string message = e.what();
-      throw std::runtime_error("ERROR in CrestClient::getPayloadMeta cannot get the payload meta info form file storage, " + message);
+      throw CrestException("ERROR in CrestClient::getPayloadMeta cannot get the payload meta info form file storage, " + message);
     }
 
     return dto;
diff --git a/src/CrestRequest.cxx b/src/CrestRequest.cxx
index 8923eee..78c2d9e 100644
--- a/src/CrestRequest.cxx
+++ b/src/CrestRequest.cxx
@@ -11,7 +11,8 @@
 
 #include <string>
 #include <map>
-#include "CrestRequest.h"
+// #include "CrestRequest.h"
+#include <CrestApi/CrestException.h>
 
 namespace Crest
 {
@@ -166,10 +167,14 @@ namespace Crest
       curl_slist_free_all(headers);
 
       curl_global_cleanup();
+
+      // error checking in the server response:
+      checkResult(res, response_code, s, method_name);
+      
       return s;
     }
 
-    throw std::runtime_error(std::string("ERROR in ") + std::string(method_name) + " | CURL not init");
+    throw CrestException(std::string("ERROR in ") + std::string(method_name) + " | CURL not init");
   }
 
   std::string CrestRequest::performRequest(const std::string &current_path, Action action, nlohmann::json &js,
@@ -350,20 +355,19 @@ namespace Crest
       // Perform the request
       res = curl_easy_perform(curl);
 
-      // Check for errors
-      if (res != CURLE_OK)
-      {
-        std::cerr << "Error performing curl request: " << curl_easy_strerror(res) << std::endl;
-      }
-      else
-      {
-        // Successful request, handle the binary response data directly
-        std::cout << "Received " << response_data.size() << " bytes of binary data." << std::endl;
-      }
+      // data to check the errors in the server response:
+      long response_code;
+      curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
+
       curl_easy_cleanup(curl);
+      
+      // error checking in the server response:
+      const char *method_name = "CrestRequest::getPayloadRequest";
+      checkResult(res, response_code, response, method_name);
+      
       return response_data;
     }
-    throw std::runtime_error(std::string("ERROR in ") + "getPayloadRequest CURL not init");
+    throw CrestException(std::string("ERROR in ") + "getPayloadRequest CURL not init");
   }
 
   std::string CrestRequest::uploadPayload(const std::string &current_path, Action action, const std::string &tag, uint64_t endtime, const nlohmann::json &js,
@@ -372,7 +376,6 @@ namespace Crest
   {
 
     CURL *curl;
-    CURLcode res;
 
     curl_global_init(CURL_GLOBAL_DEFAULT);
     curl = curl_easy_init();
@@ -501,17 +504,6 @@ namespace Crest
       // Perform the request
       CURLcode res = curl_easy_perform(curl);
 
-      // Check for errors
-      if (res != CURLE_OK)
-      {
-        std::cerr << "curl_easy_perform() failed: " << curl_easy_strerror(res) << std::endl;
-      }
-      else
-      {
-        // Successful request
-        std::cout << "Response: " << response << std::endl;
-      }
-
       // data to check the errors in the server response:
       long response_code;
       curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code);
@@ -526,12 +518,14 @@ namespace Crest
 #endif
       curl_slist_free_all(headers);
       curl_global_cleanup();
+
+      // error checking in the server response:
       checkResult(res, response_code, response, method_name);
 
       return response;
     }
     std::string mes = "ERROR in CrestRequest::uploadPayload";
-    throw std::runtime_error(mes + " | CURL not init");
+    throw CrestException(mes + " | CURL not init");
   }
   // end of REQUEST METHODS
 
@@ -599,7 +593,7 @@ namespace Crest
       std::string mes = "ERROR in ";
       mes += method_name;
       mes += " | ";
-      throw std::runtime_error(mes + std::to_string(response_code));
+      throw CrestException(mes + std::to_string(response_code));
     }
 
     // Errors, decoded from JSON CREST Server messages:
@@ -619,7 +613,7 @@ namespace Crest
       std::string mes = "ERROR in ";
       mes += method_name;
       mes += " | ";
-      throw std::runtime_error(mes + "CREST Server response : " + s);
+      throw CrestException(mes + "CREST Server response : " + s);
     }
   }
 
@@ -637,13 +631,13 @@ namespace Crest
         // method name is undefined
 
         std::string wh = e.what();
-        throw std::runtime_error("ERROR in JSON conversion: " + wh + " | In string: " + str);
+        throw CrestException("ERROR in JSON conversion: " + wh + " | In string: " + str);
       }
       else
       {
         std::string str2 = parseXMLOutput(str); // to remove HTML tags use this function
         std::string str3 = removeCR(str2);      // to remove carridge return
-        throw std::runtime_error("ERROR in " + std::string(method) + " | CREST Server response : " + str3);
+        throw CrestException("ERROR in " + std::string(method) + " | CREST Server response : " + str3);
       }
     }
   }
@@ -666,7 +660,7 @@ namespace Crest
       if (type == "error" || type == "info")
       {
         std::string message = js.value("message", " unknown message ");
-        throw std::runtime_error("ERROR in " + std::string(method) + " | CREST response: " + message);
+        throw CrestException("ERROR in " + std::string(method) + " | CREST response: " + message);
       }
     }
 
@@ -683,11 +677,11 @@ namespace Crest
         std::string message = js.value("message", "");
         if (message == "")
         {
-          throw std::runtime_error("ERROR in " + std::string(method) + " | CREST response: " + error);
+          throw CrestException("ERROR in " + std::string(method) + " | CREST response: " + error);
         }
         else
         {
-          throw std::runtime_error("ERROR in " + std::string(method) + " | CREST response: " + message);
+          throw CrestException("ERROR in " + std::string(method) + " | CREST response: " + message);
         }
       }
     }
diff --git a/test/CrestApi_test.cxx b/test/CrestApi_test.cxx
index eacc41b..dbbf5bc 100644
--- a/test/CrestApi_test.cxx
+++ b/test/CrestApi_test.cxx
@@ -264,7 +264,7 @@ BOOST_AUTO_TEST_SUITE(CrestApiTest)
       myCrestClient.removeGlobalTag(global_tag);
       std::cout << "The global tag " << global_tag << " was removed from CREST server." << std::endl;
     }
-    catch (const std::runtime_error& e) {
+    catch (const CrestException& e) {
       std::cout << "The global tag " << global_tag << " was not removed from server." << std::endl;
       res = false;
     }
@@ -282,7 +282,7 @@ BOOST_AUTO_TEST_SUITE(CrestApiTest)
       myCrestClient.removeTag(tagname);
       std::cout << "The tag " << tagname << " was removed from CREST server." << std::endl;
     }
-    catch (const std::runtime_error& e) {
+    catch (const CrestException& e) {
       std::cout << "Tag " << tagname << " was not removed from server." << std::endl;
       res = false;
     }
-- 
GitLab


From b88206bfeec7655d219e5893a05940396600d0e1 Mon Sep 17 00:00:00 2001
From: formica <andrea.formica@cern.ch>
Date: Sun, 17 Mar 2024 18:39:44 +0100
Subject: [PATCH 4/6] update cmake for standalone

---
 CMakeLists-standalone.txt  | 106 ++++++++++++++++++++++++++++++++
 CMakeLists.txt             | 101 +++++++++++++------------------
 CMakeLists.txt.atlas       | 121 +++++++++++++++++++++++++++++++++++++
 CrestApiLibConfig.cmake.in |  24 ++++++++
 4 files changed, 294 insertions(+), 58 deletions(-)
 create mode 100644 CMakeLists-standalone.txt
 create mode 100644 CMakeLists.txt.atlas
 create mode 100644 CrestApiLibConfig.cmake.in

diff --git a/CMakeLists-standalone.txt b/CMakeLists-standalone.txt
new file mode 100644
index 0000000..b0390a9
--- /dev/null
+++ b/CMakeLists-standalone.txt
@@ -0,0 +1,106 @@
+
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
+
+# In lxplus you should set the LCG view to the latest version of gcc and cmake
+# source /cvmfs/sft.cern.ch/lcg/views/LCG_104b/x86_64-centos7-gcc11-opt/setup.sh
+# Then use cmake from a build directory : cmake ..
+# Set the name of the package.
+cmake_minimum_required(VERSION 3.10)
+project( CrestApiLib )
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS ON)
+
+include(CheckCXXCompilerFlag)
+CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX11)
+CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
+if(COMPILER_SUPPORTS_CXX11)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")
+elseif(COMPILER_SUPPORTS_CXX0X)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x ")
+else()
+        message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
+endif()
+
+find_package(CURL REQUIRED)
+
+if(CURL_FOUND)
+    message(STATUS "Found CURL version: ${CURL_VERSION_STRING}")
+    message(STATUS "Using CURL include dir(s): ${CURL_INCLUDE_DIRS}")
+    message(STATUS "Using CURL lib(s): ${CURL_LIBRARIES}")
+    include_directories(${CURL_INCLUDE_DIRS})
+    ADD_DEFINITIONS( "-DHAS_CURL" )
+else()
+    message(STATUS "Fetching CURL")
+    include(FetchContent)
+    FetchContent_Declare(CURL GIT_REPOSITORY https://github.com/curl/curl.git)
+    FetchContent_MakeAvailable(CURL)
+endif()
+
+find_package(Boost COMPONENTS system thread filesystem REQUIRED)
+
+IF (Boost_FOUND)
+    INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
+    ADD_DEFINITIONS( "-DHAS_BOOST" )
+ENDIF()
+
+SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} ${Boost_INCLUDE_DIR})
+SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} ../build/CrestApi)
+
+
+# External dependencies.
+#find_package( CURL )
+#find_package( Boost )
+
+
+set(header_path "./CrestApi")
+set(HEADERS ${header_path}/CrestApi.h
+            ${header_path}/CrestModel.h
+            ${header_path}/CrestApiBase.h
+            ${header_path}/CrestApiFs.h
+            ${header_path}/CrestRequest.h
+		    ${header_path}/CrestApiExt.h
+		    ${header_path}/picosha2.h)
+
+set(SOURCES src/CrestApi.cxx src/CrestRequest.cxx src/CrestApiFs.cxx)
+
+include_directories(CrestApi ./ nlohmann ${Boost_INCLUDE_DIRS})
+set (SOURCES_EXAMPLE_FS doc/crest_example_fs.cxx)
+set (SOURCES_EXAMPLE_SRV doc/crest_example_server.cxx)
+set (SOURCES_TEST test/test-json.cxx)
+set (SOURCES_JSON_TEST test/json_parse.cxx)
+
+if(${CMAKE_INSTALL_PREFIX} STREQUAL "/usr/local") 
+    set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/../installed)
+endif()
+
+# Component(s) in the package.
+set(include_dest "${CMAKE_INSTALL_PREFIX}/include/CrestApi")
+
+add_library(CrestApiLib SHARED ${SOURCES} ${HEADERS})
+target_link_libraries(CrestApiLib ${CURL_LIBRARIES} ${Boost_LIBRARIES})
+target_include_directories(CrestApiLib PUBLIC
+                $<BUILD_INTERFACE:${headers_path}> # for headers when building
+                $<INSTALL_INTERFACE:${include_dest}> # for client in install mode
+                )
+install(TARGETS CrestApiLib EXPORT CrestApiLib DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
+install(EXPORT CrestApiLib DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
+
+add_executable(crest_example_server ${SOURCES_EXAMPLE_SRV} ${HEADERS})
+target_link_libraries(crest_example_server CrestApiLib stdc++)
+
+add_executable(crest_example_fs ${SOURCES_EXAMPLE_FS} ${HEADERS})
+target_link_libraries(crest_example_fs CrestApiLib stdc++)
+
+add_executable(test-json ${SOURCES_TEST} ${HEADERS})
+target_link_libraries(test-json CrestApiLib stdc++)
+add_executable(json_parse ${SOURCES_JSON_TEST} ${HEADERS})
+target_link_libraries(json_parse CrestApiLib stdc++)
+
+# Generate the Config.cmake file
+configure_file(CrestApiLibConfig.cmake.in CrestApiLibConfig.cmake @ONLY)
+
+install(FILES ${HEADERS} DESTINATION "${include_dest}")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CrestApiLibConfig.cmake"
+        DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/CrestApiLib")
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9836388..b0390a9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,9 +1,12 @@
 
-# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 
+# In lxplus you should set the LCG view to the latest version of gcc and cmake
+# source /cvmfs/sft.cern.ch/lcg/views/LCG_104b/x86_64-centos7-gcc11-opt/setup.sh
+# Then use cmake from a build directory : cmake ..
 # Set the name of the package.
-atlas_subdir( CrestApi )
-
+cmake_minimum_required(VERSION 3.10)
+project( CrestApiLib )
 
 set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
@@ -20,11 +23,7 @@ else()
         message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
 endif()
 
-
-# External dependencies.
-find_package(nlohmann_json REQUIRED)
 find_package(CURL REQUIRED)
-find_package( Boost COMPONENTS unit_test_framework regex timer )
 
 if(CURL_FOUND)
     message(STATUS "Found CURL version: ${CURL_VERSION_STRING}")
@@ -50,13 +49,17 @@ SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} ${Boost_INCLUDE_DIR})
 SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} ../build/CrestApi)
 
 
+# External dependencies.
+#find_package( CURL )
+#find_package( Boost )
+
+
 set(header_path "./CrestApi")
 set(HEADERS ${header_path}/CrestApi.h
             ${header_path}/CrestModel.h
             ${header_path}/CrestApiBase.h
             ${header_path}/CrestApiFs.h
             ${header_path}/CrestRequest.h
-	    ${header_path}/CrestException.h
 		    ${header_path}/CrestApiExt.h
 		    ${header_path}/picosha2.h)
 
@@ -68,54 +71,36 @@ set (SOURCES_EXAMPLE_SRV doc/crest_example_server.cxx)
 set (SOURCES_TEST test/test-json.cxx)
 set (SOURCES_JSON_TEST test/json_parse.cxx)
 
+if(${CMAKE_INSTALL_PREFIX} STREQUAL "/usr/local") 
+    set(CMAKE_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/../installed)
+endif()
+
 # Component(s) in the package.
-atlas_add_library( CrestApiLib
-   ${HEADERS} ${SOURCES}
-   PUBLIC_HEADERS CrestApi
-   LINK_LIBRARIES nlohmann_json::nlohmann_json
-   PRIVATE_INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
-   PRIVATE_LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
-
-# The CrestApi examples for the CREST server.
-atlas_add_executable(crest_example_server
-   SOURCES ${SOURCES_EXAMPLE_SRV} ${HEADERS}
-   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
-   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
-   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
-
-# The CrestApi examples for the file storage.
-atlas_add_executable(crest_example_fs 
-   SOURCES ${SOURCES_EXAMPLE_FS} ${HEADERS}
-   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
-   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
-   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
-
-# The CrestApi test.
-atlas_add_executable(test-json 
-   SOURCES ${SOURCES_TEST} ${HEADERS}
-   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
-   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
-   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
-
- # The CrestApi test.
-atlas_add_executable(json_parse
-   SOURCES ${SOURCES_JSON_TEST} ${HEADERS}
-   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
-   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
-   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
- 
-# CrestApi package test for the file storage methods (CrestApiFs.cxx).
-atlas_add_test( CrestApiFs_test
-   SOURCES test/CrestApiFs_test.cxx ${HEADERS} ${SOURCES}
-   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
-   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
-   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++
-   POST_EXEC_SCRIPT nopost.sh )
-
-# CrestApi package test for the server methods (CrestApi.cxx).
-atlas_add_test( CrestApi_test
-   SOURCES test/CrestApi_test.cxx ${HEADERS} ${SOURCES}
-   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
-   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
-   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++
-   POST_EXEC_SCRIPT nopost.sh )
+set(include_dest "${CMAKE_INSTALL_PREFIX}/include/CrestApi")
+
+add_library(CrestApiLib SHARED ${SOURCES} ${HEADERS})
+target_link_libraries(CrestApiLib ${CURL_LIBRARIES} ${Boost_LIBRARIES})
+target_include_directories(CrestApiLib PUBLIC
+                $<BUILD_INTERFACE:${headers_path}> # for headers when building
+                $<INSTALL_INTERFACE:${include_dest}> # for client in install mode
+                )
+install(TARGETS CrestApiLib EXPORT CrestApiLib DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
+install(EXPORT CrestApiLib DESTINATION "${CMAKE_INSTALL_PREFIX}/lib")
+
+add_executable(crest_example_server ${SOURCES_EXAMPLE_SRV} ${HEADERS})
+target_link_libraries(crest_example_server CrestApiLib stdc++)
+
+add_executable(crest_example_fs ${SOURCES_EXAMPLE_FS} ${HEADERS})
+target_link_libraries(crest_example_fs CrestApiLib stdc++)
+
+add_executable(test-json ${SOURCES_TEST} ${HEADERS})
+target_link_libraries(test-json CrestApiLib stdc++)
+add_executable(json_parse ${SOURCES_JSON_TEST} ${HEADERS})
+target_link_libraries(json_parse CrestApiLib stdc++)
+
+# Generate the Config.cmake file
+configure_file(CrestApiLibConfig.cmake.in CrestApiLibConfig.cmake @ONLY)
+
+install(FILES ${HEADERS} DESTINATION "${include_dest}")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/CrestApiLibConfig.cmake"
+        DESTINATION "${CMAKE_INSTALL_PREFIX}/lib/cmake/CrestApiLib")
\ No newline at end of file
diff --git a/CMakeLists.txt.atlas b/CMakeLists.txt.atlas
new file mode 100644
index 0000000..9836388
--- /dev/null
+++ b/CMakeLists.txt.atlas
@@ -0,0 +1,121 @@
+
+# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
+
+# Set the name of the package.
+atlas_subdir( CrestApi )
+
+
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS ON)
+
+include(CheckCXXCompilerFlag)
+CHECK_CXX_COMPILER_FLAG("-std=c++17" COMPILER_SUPPORTS_CXX11)
+CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
+if(COMPILER_SUPPORTS_CXX11)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ")
+elseif(COMPILER_SUPPORTS_CXX0X)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x ")
+else()
+        message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
+endif()
+
+
+# External dependencies.
+find_package(nlohmann_json REQUIRED)
+find_package(CURL REQUIRED)
+find_package( Boost COMPONENTS unit_test_framework regex timer )
+
+if(CURL_FOUND)
+    message(STATUS "Found CURL version: ${CURL_VERSION_STRING}")
+    message(STATUS "Using CURL include dir(s): ${CURL_INCLUDE_DIRS}")
+    message(STATUS "Using CURL lib(s): ${CURL_LIBRARIES}")
+    include_directories(${CURL_INCLUDE_DIRS})
+    ADD_DEFINITIONS( "-DHAS_CURL" )
+else()
+    message(STATUS "Fetching CURL")
+    include(FetchContent)
+    FetchContent_Declare(CURL GIT_REPOSITORY https://github.com/curl/curl.git)
+    FetchContent_MakeAvailable(CURL)
+endif()
+
+find_package(Boost COMPONENTS system thread filesystem REQUIRED)
+
+IF (Boost_FOUND)
+    INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
+    ADD_DEFINITIONS( "-DHAS_BOOST" )
+ENDIF()
+
+SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} ${Boost_INCLUDE_DIR})
+SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} ../build/CrestApi)
+
+
+set(header_path "./CrestApi")
+set(HEADERS ${header_path}/CrestApi.h
+            ${header_path}/CrestModel.h
+            ${header_path}/CrestApiBase.h
+            ${header_path}/CrestApiFs.h
+            ${header_path}/CrestRequest.h
+	    ${header_path}/CrestException.h
+		    ${header_path}/CrestApiExt.h
+		    ${header_path}/picosha2.h)
+
+set(SOURCES src/CrestApi.cxx src/CrestRequest.cxx src/CrestApiFs.cxx)
+
+include_directories(CrestApi ./ nlohmann ${Boost_INCLUDE_DIRS})
+set (SOURCES_EXAMPLE_FS doc/crest_example_fs.cxx)
+set (SOURCES_EXAMPLE_SRV doc/crest_example_server.cxx)
+set (SOURCES_TEST test/test-json.cxx)
+set (SOURCES_JSON_TEST test/json_parse.cxx)
+
+# Component(s) in the package.
+atlas_add_library( CrestApiLib
+   ${HEADERS} ${SOURCES}
+   PUBLIC_HEADERS CrestApi
+   LINK_LIBRARIES nlohmann_json::nlohmann_json
+   PRIVATE_INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
+   PRIVATE_LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+
+# The CrestApi examples for the CREST server.
+atlas_add_executable(crest_example_server
+   SOURCES ${SOURCES_EXAMPLE_SRV} ${HEADERS}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+
+# The CrestApi examples for the file storage.
+atlas_add_executable(crest_example_fs 
+   SOURCES ${SOURCES_EXAMPLE_FS} ${HEADERS}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+
+# The CrestApi test.
+atlas_add_executable(test-json 
+   SOURCES ${SOURCES_TEST} ${HEADERS}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+
+ # The CrestApi test.
+atlas_add_executable(json_parse
+   SOURCES ${SOURCES_JSON_TEST} ${HEADERS}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} PUBLIC_HEADERS
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++ )
+ 
+# CrestApi package test for the file storage methods (CrestApiFs.cxx).
+atlas_add_test( CrestApiFs_test
+   SOURCES test/CrestApiFs_test.cxx ${HEADERS} ${SOURCES}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++
+   POST_EXEC_SCRIPT nopost.sh )
+
+# CrestApi package test for the server methods (CrestApi.cxx).
+atlas_add_test( CrestApi_test
+   SOURCES test/CrestApi_test.cxx ${HEADERS} ${SOURCES}
+   LINK_LIBRARIES CrestApiLib nlohmann_json::nlohmann_json
+   INCLUDE_DIRS ${CURL_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
+   LINK_LIBRARIES ${CURL_LIBRARIES} ${Boost_LIBRARIES} stdc++
+   POST_EXEC_SCRIPT nopost.sh )
diff --git a/CrestApiLibConfig.cmake.in b/CrestApiLibConfig.cmake.in
new file mode 100644
index 0000000..7e38c81
--- /dev/null
+++ b/CrestApiLibConfig.cmake.in
@@ -0,0 +1,24 @@
+# - Check if the user provided a path to CrestApiLib_INCLUDE_DIRS.
+#   If not, set it to the correct include directory.
+if(NOT CrestApiLib_INCLUDE_DIRS)
+    set(CrestApiLib_INCLUDE_DIRS "@CrestApiLib_INSTALL_PREFIX@/include")
+endif()
+
+# Create a CrestApiLib::CrestApiLib target to be used by consumers of CrestApiLib
+add_library(CrestApiLib::CrestApiLib INTERFACE IMPORTED)
+set_target_properties(CrestApiLib::CrestApiLib PROPERTIES
+    INTERFACE_INCLUDE_DIRECTORIES "${CrestApiLib_INCLUDE_DIRS}"
+)
+
+# Set variables to help consumers locate CrestApiLib library and headers
+set(CrestApiLib_FOUND TRUE)
+set(CrestApiLib_INCLUDE_DIRS "${CrestApiLib_INCLUDE_DIRS}")
+set(CrestApiLib_LIBRARIES CrestApiLib::CrestApiLib)
+
+# Provide configuration results
+include(CMakeFindDependencyMacro)
+if(NOT TARGET CURL::CURL) # This condition is optional and can be modified based on your dependencies
+    find_dependency(CURL REQUIRED)
+endif()
+
+include("${CMAKE_CURRENT_LIST_DIR}/../../CrestApiLib.cmake")
-- 
GitLab


From 11d5908a03d855a3e8f0f0e6cd487cb35c32fb60 Mon Sep 17 00:00:00 2001
From: formica <andrea.formica@cern.ch>
Date: Sun, 17 Mar 2024 18:49:04 +0100
Subject: [PATCH 5/6] Add exception header in cmake.

---
 CMakeLists.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index b0390a9..17b89cf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -61,6 +61,7 @@ set(HEADERS ${header_path}/CrestApi.h
             ${header_path}/CrestApiFs.h
             ${header_path}/CrestRequest.h
 		    ${header_path}/CrestApiExt.h
+		    ${header_path}/CrestException.h
 		    ${header_path}/picosha2.h)
 
 set(SOURCES src/CrestApi.cxx src/CrestRequest.cxx src/CrestApiFs.cxx)
-- 
GitLab


From 8e32cc34d2f2cf15439c8ed9fa0e48f8fb59ff04 Mon Sep 17 00:00:00 2001
From: formica <andrea.formica@cern.ch>
Date: Sun, 17 Mar 2024 18:49:22 +0100
Subject: [PATCH 6/6] Add exception header in cmake.

---
 CMakeLists-standalone.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/CMakeLists-standalone.txt b/CMakeLists-standalone.txt
index b0390a9..17b89cf 100644
--- a/CMakeLists-standalone.txt
+++ b/CMakeLists-standalone.txt
@@ -61,6 +61,7 @@ set(HEADERS ${header_path}/CrestApi.h
             ${header_path}/CrestApiFs.h
             ${header_path}/CrestRequest.h
 		    ${header_path}/CrestApiExt.h
+		    ${header_path}/CrestException.h
 		    ${header_path}/picosha2.h)
 
 set(SOURCES src/CrestApi.cxx src/CrestRequest.cxx src/CrestApiFs.cxx)
-- 
GitLab