From 2f5823a7d5c6f9829984a61fd80cb038de44db13 Mon Sep 17 00:00:00 2001
From: Mikhail Mineev <Mikhail.Mineev@cern.ch>
Date: Fri, 27 Sep 2024 22:10:23 +0200
Subject: [PATCH] PayloadTagInfoDto class added

---
 CrestApi/CrestApi.h               | 11 ++++++
 CrestApi/CrestModel.h             | 32 +++++++++++++++++
 examples/crest_example_server.cxx | 15 ++++++++
 src/CrestApi.cxx                  | 26 ++++++++++++++
 src/CrestApiFs.cxx                |  2 +-
 src/CrestModel.cxx                | 58 ++++++++++++++++++++++++++++++-
 6 files changed, 142 insertions(+), 2 deletions(-)

diff --git a/CrestApi/CrestApi.h b/CrestApi/CrestApi.h
index 87a0013..284caf3 100644
--- a/CrestApi/CrestApi.h
+++ b/CrestApi/CrestApi.h
@@ -491,6 +491,17 @@ namespace Crest
  */
         std::string getCrestVersion();
 
+/**
+ * This method retrieves monitoring information on payload as a list of payload tag information.
+ * @param tagname - tag name pattern, "%" can be used for any symbols,
+ * @param size - page size,
+ * @param page - page number,
+ * @param sort - sorting order (name:ASC or name:DESC),
+ * @return JSON payload tag info list as a PayloadTagInfoSetDto.<br>
+ */
+        PayloadTagInfoSetDto listPayloadTagInfo(const std::string &tagname, int size, int page, const std::string &sort);
+
+
     };
 
 } // namespace Crest
diff --git a/CrestApi/CrestModel.h b/CrestApi/CrestModel.h
index b8938d9..a9333a6 100644
--- a/CrestApi/CrestModel.h
+++ b/CrestApi/CrestModel.h
@@ -390,4 +390,36 @@ public:
     static PayloadSetDto from_json(const json &j);
 };
 
+class PayloadTagInfoDto
+{
+public:
+    std::string tagname;
+    int niovs;
+    double totvolume;
+    double avgvolume;
+
+    // Ctor
+    PayloadTagInfoDto(std::string _tagname, int _niovs, double _totvolume, double _avgvolume):
+      tagname(_tagname), niovs(_niovs), totvolume(_totvolume), avgvolume(_avgvolume){
+
+    }
+    // Default Ctor
+    PayloadTagInfoDto(): tagname(""), niovs(0), totvolume(0.0), avgvolume(0.0) {}
+    json to_json() const;
+    static PayloadTagInfoDto from_json(const json &j);
+};
+
+class PayloadTagInfoSetDto : public CrestBaseResponse
+{
+public:
+    std::vector<PayloadTagInfoDto> resources;
+    const char* getFormat() const {return "PayloadTagInfoSetDto";}
+    int64_t getSize() const{return resources.size();}
+
+    json to_json() const;
+
+    static PayloadTagInfoSetDto from_json(const json &j);
+};
+
+
 #endif // CREST_DTOS_HPP
diff --git a/examples/crest_example_server.cxx b/examples/crest_example_server.cxx
index 7ea3c5d..041e253 100644
--- a/examples/crest_example_server.cxx
+++ b/examples/crest_example_server.cxx
@@ -539,6 +539,21 @@ void testFindExistingTagMeta(const std::string &tagname)
   }
 }
 
+void testListPayloadTagInfo(const std::string& tagname, int size, int page, const std::string &sort) {
+  std::cout << std::endl << "test: listPayloadTagInfo" << std::endl;
+  CrestClient myCrestClient = CrestClient(SURL,false);
+
+  try {
+    PayloadTagInfoSetDto dto = myCrestClient.listPayloadTagInfo(tagname,size,page,sort);
+    std::cout << std::endl << "test: listPayloadTagInfo (result) = " << std::endl
+              << dto.to_json().dump(4) << std::endl;
+  }
+  catch (const std::exception& e) {
+    std::cout << std::endl << "test: listPayloadTagInfo (failed)" << std::endl;
+    std::cout << e.what() << std::endl;
+  }
+}
+
 
 
 int main(int argc, char* argv[]) {
diff --git a/src/CrestApi.cxx b/src/CrestApi.cxx
index a2548de..8d80309 100644
--- a/src/CrestApi.cxx
+++ b/src/CrestApi.cxx
@@ -829,6 +829,32 @@ namespace Crest
 	PayloadDto dto = PayloadDto::from_json(response);
 	return dto;
     }
+
+    PayloadTagInfoSetDto CrestClient::listPayloadTagInfo(const std::string &tagname, int size, int page, const std::string &sort)
+    {
+        const char *method_name = "CrestClient::listPayloadTagInfo";
+
+        std::string current_path = m_PATH;
+        current_path += s_MONITORING_PAYLOAD_PATH;
+        current_path += "?tagname=";
+        current_path += tagname;
+
+        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;
+        retv = m_request.performRequest(current_path, GET, js, method_name);
+        nlohmann::json response = getJson(retv, method_name);
+        PayloadTagInfoSetDto dto = PayloadTagInfoSetDto::from_json(response);
+
+        return dto;
+    }
+
  
 } // namespace Crest
 
diff --git a/src/CrestApiFs.cxx b/src/CrestApiFs.cxx
index 3ae52c7..d8ab237 100644
--- a/src/CrestApiFs.cxx
+++ b/src/CrestApiFs.cxx
@@ -667,7 +667,7 @@ namespace Crest
 
   IovSetDto CrestFsClient::storeIovs(const IovSetDto &iovsetdto)
   {
-    checkFsException("CrestFsClient::selectGroups");
+    checkFsException("CrestFsClient::storeIovs");
     return IovSetDto();
   }
 
diff --git a/src/CrestModel.cxx b/src/CrestModel.cxx
index a1905c2..84886c3 100644
--- a/src/CrestModel.cxx
+++ b/src/CrestModel.cxx
@@ -206,7 +206,8 @@ TagDto TagDto::from_json(const json &j)
     tag.endOfValidity = j.value<uint64_t>("endOfValidity", 0);
     if (j.contains(std::string{"insertionTime"}))
         tag.insertionTime = j.value("insertionTime", "");
-    tag.modificationTime = j.value("modificationTime", "");
+    if (j.contains(std::string{"modificationTime"}))
+        tag.modificationTime = j.value("modificationTime", "");
     return tag;
 }
 json TagSetDto::to_json() const
@@ -627,3 +628,58 @@ PayloadSetDto PayloadSetDto::from_json(const json &j)
 
     return payloadSetDto;
 }
+
+//  PayloadTagInfoDto
+
+json PayloadTagInfoDto::to_json() const
+{
+    json js = {};
+    js["tagname"] = tagname;
+    js["niovs"] = niovs;
+    js["totvolume"] = totvolume;
+    js["avgvolume"] = avgvolume;
+    return js;
+}
+
+PayloadTagInfoDto PayloadTagInfoDto::from_json(const json &j)
+{
+    PayloadTagInfoDto dto;
+    auto it = j.find("tagname");
+    if (it != j.end())
+    {
+        dto.tagname = j["tagname"];
+    }
+    else
+    {
+        throw Crest::CrestException("ERROR in PayloadTagInfoDto.from_json: JSON contains no tag name.");
+    }
+    dto.niovs = j.value("niovs", 0);
+    dto.totvolume = j.value("totvolume", 0.0);
+    dto.avgvolume = j.value("avgvolume", 0.0);
+    return dto;
+}
+
+json PayloadTagInfoSetDto::to_json() const
+{
+    json baseJson = CrestBaseResponse::to_json();
+    json jsonResources = json::array();
+    for (const auto &resource : resources)
+    {
+        jsonResources.push_back(((PayloadTagInfoDto)resource).to_json());
+    }
+    baseJson["resources"] = jsonResources;
+    return baseJson;
+}
+
+PayloadTagInfoSetDto PayloadTagInfoSetDto::from_json(const json &j)
+{
+    PayloadTagInfoSetDto pSet;
+    pSet.load_from_json(j);
+    json jsonResources = j.value("resources", json::array());
+    for (auto it = jsonResources.begin(); it != jsonResources.end(); ++it)
+    {
+        pSet.resources.push_back(PayloadTagInfoDto::from_json(*it));
+    }
+
+    return pSet;
+}
-- 
GitLab