XRootD
XrdHttpTapeApiStore Class Reference

#include <XrdHttpTapeApiStore.hh>

+ Collaboration diagram for XrdHttpTapeApiStore:

Classes

struct  Status
 

Public Member Functions

 XrdHttpTapeApiStore (std::filesystem::path root)
 
Status ArchiveInfo (const nlohmann::json &paths, nlohmann::json &response)
 
Status CancelStage (const std::string &requestId, const nlohmann::json &paths)
 
Status CreateStage (const nlohmann::json &files, std::string &requestId)
 
Status DeleteStage (const std::string &requestId)
 
Status GetStage (const std::string &requestId, nlohmann::json &response)
 
Status Initialize ()
 
Status Release (const std::string &requestId, const nlohmann::json &paths)
 

Detailed Description

Definition at line 21 of file XrdHttpTapeApiStore.hh.

Constructor & Destructor Documentation

◆ XrdHttpTapeApiStore()

XrdHttpTapeApiStore::XrdHttpTapeApiStore ( std::filesystem::path  root)
explicit

Definition at line 60 of file XrdHttpTapeApiStore.cc.

61  : m_root(std::move(root)),
62  m_archiveRoot(m_root / "archive"),
63  m_diskRoot(m_root / "disk"),
64  m_requestsRoot(m_root / "requests")
65 {
66 }

Member Function Documentation

◆ ArchiveInfo()

XrdHttpTapeApiStore::Status XrdHttpTapeApiStore::ArchiveInfo ( const nlohmann::json &  paths,
nlohmann::json &  response 
)

Definition at line 381 of file XrdHttpTapeApiStore.cc.

383 {
384  std::lock_guard<std::mutex> lock(m_mutex);
385  response = Json::array();
386  for(const auto &path : paths)
387  {
388  Json item;
389  std::string normalized;
390  fs::path archivePath;
391  Status status = ResolvePath(m_archiveRoot, path.get<std::string>(),
392  normalized, archivePath);
393  item["path"] = status ? normalized : path.get<std::string>();
394 
395  fs::path diskPath;
396  if(status) status = ResolvePath(m_diskRoot, normalized,
397  normalized, diskPath);
398  bool archived = false;
399  if(status && !IsRegularFile(archivePath, archived))
400  {
401  status = Error(500, "could not inspect the archived file");
402  }
403  bool onDisk = false;
404  if(status && !IsRegularFile(diskPath, onDisk))
405  {
406  status = Error(500, "could not inspect the disk file");
407  }
408 
409  if(!status)
410  {
411  item["error"] = status.message;
412  }
413  else if(archived && onDisk)
414  {
415  item["locality"] = "DISK_AND_TAPE";
416  }
417  else if(archived)
418  {
419  item["locality"] = "TAPE";
420  }
421  else if(onDisk)
422  {
423  item["locality"] = "DISK";
424  }
425  else
426  {
427  item["error"] = "file does not exist";
428  }
429  response.push_back(std::move(item));
430  }
431  return {};
432 }
@ Error

References Error, and XrdHttpTapeApiStore::Status::message.

◆ CancelStage()

XrdHttpTapeApiStore::Status XrdHttpTapeApiStore::CancelStage ( const std::string &  requestId,
const nlohmann::json &  paths 
)

Definition at line 329 of file XrdHttpTapeApiStore.cc.

331 {
332  std::lock_guard<std::mutex> lock(m_mutex);
333  Json request;
334  Status status = ReadRequest(requestId, request);
335  if(!status) return status;
336  std::vector<std::string> normalized;
337  return ValidateRequestPaths(request, paths, normalized);
338 }

◆ CreateStage()

XrdHttpTapeApiStore::Status XrdHttpTapeApiStore::CreateStage ( const nlohmann::json &  files,
std::string &  requestId 
)

Definition at line 219 of file XrdHttpTapeApiStore.cc.

221 {
222  std::lock_guard<std::mutex> lock(m_mutex);
223  requestId = GenerateRequestId();
224  const std::uint64_t createdAt = Now();
225  Json request = {
226  {"id", requestId},
227  {"createdAt", createdAt},
228  {"startedAt", createdAt},
229  {"files", Json::array()}
230  };
231 
232  for(const auto &input : files)
233  {
234  Json file = input;
235  std::string normalized;
236  fs::path archivePath;
237  Status status = ResolvePath(m_archiveRoot,
238  input.at("path").get<std::string>(),
239  normalized, archivePath);
240  file["path"] = normalized;
241  file["startedAt"] = createdAt;
242 
243  fs::path diskPath;
244  if(status) status = ResolvePath(m_diskRoot, normalized,
245  normalized, diskPath);
246  bool archived = false;
247  if(status && !IsRegularFile(archivePath, archived))
248  {
249  status = Error(500, "could not inspect the archived file");
250  }
251  std::error_code error;
252  if(status && archived && fs::file_size(archivePath, error) == 0)
253  {
254  status = Error(400, "zero-length files cannot be staged from tape");
255  }
256  if(error) status = Error(500, "could not inspect the archived file");
257 
258  bool onDisk = false;
259  if(status && !IsRegularFile(diskPath, onDisk))
260  {
261  status = Error(500, "could not inspect the disk file");
262  }
263  if(status && archived && !onDisk)
264  {
265  error.clear();
266  fs::create_directories(diskPath.parent_path(), error);
267  if(!error)
268  {
269  fs::copy_file(archivePath, diskPath, fs::copy_options::overwrite_existing,
270  error);
271  }
272  if(error) status = Error(500, "could not stage the archived file");
273  }
274  file["finishedAt"] = Now();
275  if(status && archived)
276  {
277  file["state"] = "COMPLETED";
278  }
279  else
280  {
281  file["state"] = "FAILED";
282  file["error"] = status ? "file is not stored on tape" : status.message;
283  }
284  request["files"].push_back(std::move(file));
285  }
286 
287  request["completedAt"] = Now();
288  return WriteRequest(request);
289 }

References Error, and XrdHttpTapeApiStore::Status::message.

◆ DeleteStage()

XrdHttpTapeApiStore::Status XrdHttpTapeApiStore::DeleteStage ( const std::string &  requestId)

Definition at line 340 of file XrdHttpTapeApiStore.cc.

342 {
343  std::lock_guard<std::mutex> lock(m_mutex);
344  Json request;
345  Status status = ReadRequest(requestId, request);
346  if(!status) return status;
347 
348  std::error_code error;
349  if(!fs::remove(m_requestsRoot / (requestId + ".json"), error) || error)
350  {
351  return Error(500, "could not delete the stage request");
352  }
353  return {};
354 }

References Error.

◆ GetStage()

XrdHttpTapeApiStore::Status XrdHttpTapeApiStore::GetStage ( const std::string &  requestId,
nlohmann::json &  response 
)

Definition at line 291 of file XrdHttpTapeApiStore.cc.

293 {
294  std::lock_guard<std::mutex> lock(m_mutex);
295  Json request;
296  const Status status = ReadRequest(requestId, request);
297  if(!status) return status;
298  response = StatusResponse(request);
299  return {};
300 }

◆ Initialize()

XrdHttpTapeApiStore::Status XrdHttpTapeApiStore::Initialize ( )

Definition at line 68 of file XrdHttpTapeApiStore.cc.

69 {
70  std::error_code error;
71  fs::create_directories(m_archiveRoot, error);
72  if(error) return Error(500, "could not create the tape archive directory");
73  fs::create_directories(m_diskRoot, error);
74  if(error) return Error(500, "could not create the disk directory");
75  fs::create_directories(m_requestsRoot, error);
76  if(error) return Error(500, "could not create the request directory");
77 
78  m_root = fs::weakly_canonical(m_root, error);
79  if(error) return Error(500, "could not resolve the Tape API directory");
80  m_archiveRoot = m_root / "archive";
81  m_diskRoot = m_root / "disk";
82  m_requestsRoot = m_root / "requests";
83  return {};
84 }

References Error.

◆ Release()

XrdHttpTapeApiStore::Status XrdHttpTapeApiStore::Release ( const std::string &  requestId,
const nlohmann::json &  paths 
)

Definition at line 356 of file XrdHttpTapeApiStore.cc.

358 {
359  std::lock_guard<std::mutex> lock(m_mutex);
360  Json request;
361  Status status = ReadRequest(requestId, request);
362  if(!status) return status;
363 
364  std::vector<std::string> normalized;
365  status = ValidateRequestPaths(request, paths, normalized);
366  if(!status) return status;
367 
368  for(const auto &path : normalized)
369  {
370  std::string ignored;
371  fs::path diskPath;
372  status = ResolvePath(m_diskRoot, path, ignored, diskPath);
373  if(!status) return status;
374  std::error_code error;
375  fs::remove(diskPath, error);
376  if(error) return Error(500, "could not release the disk replica");
377  }
378  return {};
379 }

References Error.


The documentation for this class was generated from the following files: