XRootD
Loading...
Searching...
No Matches
XrdClHttp::TapeOperation Class Reference

#include <XrdClHttpTape.hh>

Collaboration diagram for XrdClHttp::TapeOperation:

Classes

struct  Impl

Public Member Functions

 TapeOperation (const std::string &url, const std::vector< std::string > &fileList, XrdCl::PrepareFlags::Flags flags)
 TapeOperation (const std::string &url, XrdCl::QueryCode::Code queryCode, const XrdCl::Buffer &arg)
 TapeOperation (const TapeOperation &)=delete
 ~TapeOperation ()
XrdCl::XRootDStatus Advance (CURL *curl, long statusCode, const std::string &body, TapeHttpRequest &request, std::string &response, bool &complete)
TapeOperation & operator= (const TapeOperation &)=delete
XrdCl::XRootDStatus Start (TapeHttpRequest &request)

Detailed Description

Definition at line 51 of file XrdClHttpTape.hh.

Constructor & Destructor Documentation

◆ TapeOperation() [1/3]

XrdClHttp::TapeOperation::TapeOperation ( const std::string & url,
const std::vector< std::string > & fileList,
XrdCl::PrepareFlags::Flags flags )

Definition at line 829 of file XrdClHttpTape.cc.

832 :
833 pImpl(std::make_unique<Impl>())
834 {
835 pImpl->storageUrl = url;
836 pImpl->initialStatus = ValidateTapePrepareFlags(flags);
837 if(!pImpl->initialStatus.IsOK()) return;
838
840 {
841 pImpl->kind = Impl::Kind::Stage;
842 pImpl->initialStatus = PrepareStageFiles(fileList, pImpl->stageFiles);
843 return;
844 }
845
846 if(fileList.size() < 2)
847 {
848 pImpl->initialStatus = ErrorStatus(XrdCl::errInvalidArgs,
849 "cancel and evict require a request id and at least one path");
850 return;
851 }
852
853 pImpl->requestId = fileList.front();
854 if(!IsValidRequestId(pImpl->requestId))
855 {
856 pImpl->initialStatus = ErrorStatus(XrdCl::errInvalidArgs,
857 "cancel and evict require a non-empty request id");
858 return;
859 }
860 pImpl->initialStatus = PathsFromInputs(
861 std::vector<std::string>(fileList.begin() + 1, fileList.end()),
862 pImpl->paths);
863 if(!pImpl->initialStatus.IsOK()) return;
864 pImpl->kind = (flags & XrdCl::PrepareFlags::Cancel)
865 ? Impl::Kind::StageCancel : Impl::Kind::Release;
866 }
const uint16_t errInvalidArgs
@ Cancel
cancel staging request

References XrdCl::PrepareFlags::Cancel, XrdCl::errInvalidArgs, XrdClHttp::TapeOperation::Impl::Release, XrdCl::PrepareFlags::Stage, XrdClHttp::TapeOperation::Impl::Stage, and XrdClHttp::TapeOperation::Impl::StageCancel.

Referenced by TapeOperation(), and operator=().

Here is the caller graph for this function:

◆ TapeOperation() [2/3]

XrdClHttp::TapeOperation::TapeOperation ( const std::string & url,
XrdCl::QueryCode::Code queryCode,
const XrdCl::Buffer & arg )

Definition at line 868 of file XrdClHttpTape.cc.

871 :
872 pImpl(std::make_unique<Impl>())
873 {
874 pImpl->storageUrl = url;
875 std::vector<std::string> args;
876 XrdCl::Utils::splitString(args, arg.ToString(), "\n");
877 if(queryCode == XrdCl::QueryCode::Prepare)
878 {
879 if(args.size() != 1 || !IsValidRequestId(args.front()))
880 {
881 pImpl->initialStatus = ErrorStatus(XrdCl::errInvalidArgs,
882 "prepare query expects a single request id");
883 return;
884 }
885 pImpl->kind = Impl::Kind::StageStatus;
886 pImpl->requestId = args.front();
887 return;
888 }
889
890 if(queryCode != XrdCl::QueryCode::Opaque)
891 {
892 pImpl->initialStatus = ErrorStatus(XrdCl::errNotSupported,
893 "unsupported HTTP query");
894 return;
895 }
896 if(args.empty() || args.front().find('\r') != std::string::npos)
897 {
898 pImpl->initialStatus = ErrorStatus(XrdCl::errInvalidArgs,
899 "missing opaque query command");
900 return;
901 }
902
903 if(args.front() == "tape.discover")
904 {
905 pImpl->kind = Impl::Kind::Discover;
906 return;
907 }
908 if(args.front() == "tape.stage_delete")
909 {
910 if(args.size() != 2 || !IsValidRequestId(args[1]))
911 {
912 pImpl->initialStatus = ErrorStatus(XrdCl::errInvalidArgs,
913 "tape.stage_delete expects a request id");
914 return;
915 }
916 pImpl->kind = Impl::Kind::StageDelete;
917 pImpl->requestId = args[1];
918 return;
919 }
920 if(args.front() == "tape.archiveinfo")
921 {
922 if(args.size() < 2)
923 {
924 pImpl->initialStatus = ErrorStatus(XrdCl::errInvalidArgs,
925 "tape.archiveinfo expects non-empty URLs");
926 return;
927 }
928 pImpl->urls.assign(args.begin() + 1, args.end());
929 for(const auto &archiveUrl : pImpl->urls)
930 {
931 if(archiveUrl.find('\r') != std::string::npos)
932 {
933 pImpl->initialStatus = ErrorStatus(XrdCl::errInvalidArgs,
934 "tape.archiveinfo expects non-empty URLs");
935 return;
936 }
937 }
938 pImpl->initialStatus = ValidateArchiveUrls(pImpl->urls, pImpl->paths);
939 if(pImpl->initialStatus.IsOK()) pImpl->kind = Impl::Kind::ArchiveInfo;
940 return;
941 }
942
943 pImpl->initialStatus = ErrorStatus(XrdCl::errNotSupported,
944 "unsupported HTTP opaque query");
945 }
std::string ToString() const
Convert the buffer to a string.
static void splitString(Container &result, const std::string &input, const std::string &delimiter)
Split a string.
Definition XrdClUtils.hh:56
const uint16_t errNotSupported
@ Opaque
Implementation dependent.
@ Prepare
Query prepare status.

References XrdClHttp::TapeOperation::Impl::ArchiveInfo, XrdClHttp::TapeOperation::Impl::Discover, XrdCl::errInvalidArgs, XrdCl::errNotSupported, XrdCl::QueryCode::Opaque, XrdCl::QueryCode::Prepare, XrdCl::Utils::splitString(), XrdClHttp::TapeOperation::Impl::StageDelete, XrdClHttp::TapeOperation::Impl::StageStatus, and XrdCl::Buffer::ToString().

Here is the call graph for this function:

◆ ~TapeOperation()

XrdClHttp::TapeOperation::~TapeOperation ( )
default

◆ TapeOperation() [3/3]

XrdClHttp::TapeOperation::TapeOperation ( const TapeOperation & )
delete

References TapeOperation().

Here is the call graph for this function:

Member Function Documentation

◆ Advance()

XrdCl::XRootDStatus XrdClHttp::TapeOperation::Advance ( CURL * curl,
long statusCode,
const std::string & body,
TapeHttpRequest & request,
std::string & response,
bool & complete )

Definition at line 973 of file XrdClHttpTape.cc.

980 {
981 complete = false;
982 response.clear();
983
984 if(pImpl->phase == Impl::Phase::Discovery)
985 {
986 if(statusCode != 200)
987 {
988 complete = true;
989 return UnexpectedStatus(statusCode, body, "Tape REST discovery");
990 }
991
992 TapeEndpoint endpoint;
993 XrdCl::XRootDStatus status = ParseDiscoveryResponse(body, endpoint);
994 if(!status.IsOK())
995 {
996 complete = true;
997 return status;
998 }
999 if(pImpl->kind == Impl::Kind::Discover)
1000 {
1001 Json result;
1002 result["uri"] = endpoint.uri;
1003 result["version"] = endpoint.version;
1004 result["sitename"] = endpoint.sitename;
1005 response = result.dump();
1006 complete = true;
1007 pImpl->phase = Impl::Phase::Complete;
1008 return XrdCl::XRootDStatus();
1009 }
1010
1011 request = TapeHttpRequest();
1012 const std::string encodedRequestId = pImpl->requestId.empty()
1013 ? "" : PercentEncodeUrlPathSegment(pImpl->requestId, curl);
1014 switch(pImpl->kind)
1015 {
1016 case Impl::Kind::Stage:
1017 {
1018 std::string error;
1019 Json stageBody = StageRequestBody(pImpl->stageFiles, error);
1020 if(!error.empty())
1021 {
1022 complete = true;
1023 return ErrorStatus(XrdCl::errInvalidArgs, error);
1024 }
1025 request.method = HttpVerb::POST;
1026 request.url = XrdOucUtils::JoinUrl(endpoint.uri, "/stage");
1027 request.body = stageBody.dump();
1028 break;
1029 }
1031 request.url = XrdOucUtils::JoinUrl(
1032 endpoint.uri, "/stage/" + encodedRequestId);
1033 break;
1035 SetPathsPostRequest(request, endpoint.uri,
1036 "/stage/" + encodedRequestId + "/cancel", pImpl->paths);
1037 break;
1039 request.method = HttpVerb::DELETE;
1040 request.url = XrdOucUtils::JoinUrl(
1041 endpoint.uri, "/stage/" + encodedRequestId);
1042 break;
1044 SetPathsPostRequest(request, endpoint.uri,
1045 "/release/" + encodedRequestId, pImpl->paths);
1046 break;
1048 SetPathsPostRequest(request, endpoint.uri, "/archiveinfo",
1049 pImpl->paths);
1050 break;
1053 complete = true;
1054 return ErrorStatus(XrdCl::errInternal,
1055 "invalid Tape REST operation state");
1056 }
1057 pImpl->phase = Impl::Phase::Request;
1058 return XrdCl::XRootDStatus();
1059 }
1060
1061 if(pImpl->phase != Impl::Phase::Request)
1062 {
1063 complete = true;
1064 return ErrorStatus(XrdCl::errInternal,
1065 "invalid Tape REST response state");
1066 }
1067
1068 complete = true;
1069 pImpl->phase = Impl::Phase::Complete;
1070 switch(pImpl->kind)
1071 {
1072 case Impl::Kind::Stage:
1073 {
1074 if(statusCode != 201)
1075 return UnexpectedStatus(statusCode, body, "stage request submission");
1076 Json json;
1077 XrdCl::XRootDStatus status =
1078 ParseJsonResponse(body, "stage submission", json);
1079 if(!status.IsOK()) return status;
1080 if(!json.contains("requestId") || !json["requestId"].is_string()
1081 || json["requestId"].get_ref<const std::string &>().empty())
1082 {
1083 return ErrorStatus(XrdCl::errInvalidResponse,
1084 "stage submission response does not contain a non-empty string "
1085 "requestId");
1086 }
1087 response = json["requestId"].get<std::string>();
1088 return XrdCl::XRootDStatus();
1089 }
1091 {
1092 if(statusCode != 200)
1093 return UnexpectedStatus(statusCode, body, "stage request polling");
1094 Json json;
1095 XrdCl::XRootDStatus status =
1096 ParseJsonResponse(body, "stage polling", json);
1097 if(!status.IsOK()) return status;
1098 Json normalizedStatus;
1099 status = NormalizeStageStatusJson(json, normalizedStatus);
1100 if(status.IsOK()) response = normalizedStatus.dump();
1101 return status;
1102 }
1104 return EmptyResponseStatus(statusCode, body,
1105 "stage request cancellation");
1107 return EmptyResponseStatus(statusCode, body, "stage request deletion");
1109 return EmptyResponseStatus(statusCode, body, "stage request release");
1111 if(statusCode != 200)
1112 return UnexpectedStatus(statusCode, body, "archiveinfo call");
1113 return ParseArchiveInfoResponse(body, pImpl->urls, pImpl->paths,
1114 response);
1117 return ErrorStatus(XrdCl::errInternal,
1118 "invalid Tape REST operation state");
1119 }
1120 return ErrorStatus(XrdCl::errInternal, "invalid Tape REST operation");
1121 }
nlohmann::json json
static std::string JoinUrl(const std::string &base, const std::string &path)
const uint16_t errInternal
Internal error.
const uint16_t errInvalidResponse
bool IsOK() const
We're fine.

References XrdClHttp::TapeOperation::Impl::ArchiveInfo, XrdClHttp::TapeHttpRequest::body, XrdClHttp::TapeOperation::Impl::Complete, XrdClHttp::DELETE, XrdClHttp::TapeOperation::Impl::Discover, XrdClHttp::TapeOperation::Impl::Discovery, XrdCl::errInternal, XrdCl::errInvalidArgs, XrdCl::errInvalidResponse, XrdClHttp::TapeOperation::Impl::Invalid, XrdCl::Status::IsOK(), XrdOucUtils::JoinUrl(), XrdClHttp::TapeHttpRequest::method, XrdClHttp::POST, XrdClHttp::TapeOperation::Impl::Release, XrdClHttp::TapeOperation::Impl::Request, XrdClHttp::TapeOperation::Impl::Stage, XrdClHttp::TapeOperation::Impl::StageCancel, XrdClHttp::TapeOperation::Impl::StageDelete, XrdClHttp::TapeOperation::Impl::StageStatus, and XrdClHttp::TapeHttpRequest::url.

Referenced by operator=().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ operator=()

TapeOperation & XrdClHttp::TapeOperation::operator= ( const TapeOperation & )
delete

References TapeOperation(), Advance(), and Start().

Here is the call graph for this function:

◆ Start()

XrdCl::XRootDStatus XrdClHttp::TapeOperation::Start ( TapeHttpRequest & request)

Definition at line 949 of file XrdClHttpTape.cc.

950 {
951 if(!pImpl->initialStatus.IsOK()) return pImpl->initialStatus;
952 if(pImpl->kind == Impl::Kind::Invalid)
953 {
954 return ErrorStatus(XrdCl::errNotSupported,
955 "unsupported HTTP Tape REST operation");
956 }
957
958 std::string endpoint;
959 std::string path;
960 std::string error;
961 if(!UrlEndpointAndPath(pImpl->storageUrl, endpoint, path, error))
962 {
963 return ErrorStatus(XrdCl::errInvalidArgs, error);
964 }
965
966 request = TapeHttpRequest();
967 request.url = XrdOucUtils::JoinUrl(
968 endpoint, "/.well-known/wlcg-tape-rest-api");
969 pImpl->phase = Impl::Phase::Discovery;
970 return XrdCl::XRootDStatus();
971 }

References XrdClHttp::TapeOperation::Impl::Discovery, XrdCl::errInvalidArgs, XrdCl::errNotSupported, XrdClHttp::TapeOperation::Impl::Invalid, XrdOucUtils::JoinUrl(), and XrdClHttp::TapeHttpRequest::url.

Referenced by operator=().

Here is the call graph for this function:
Here is the caller graph for this function:

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