From 13b434668304a51d30c5d272fc3458e4b435029c Mon Sep 17 00:00:00 2001 From: Michael Davis <michael.davis@cern.ch> Date: Tue, 9 Aug 2022 10:07:00 +0200 Subject: [PATCH] Resolve "CTA Frontend protobuf changes to support dCache" --- frontend-grpc/FrontendGRpcSvc.cpp | 200 ++++++++++-------- frontend-grpc/FrontendGRpcSvc.h | 14 +- .../protobuf/cta_grpc_frontend.proto | 123 +++++------ xrootd-ssi-protobuf-interface | 2 +- 4 files changed, 178 insertions(+), 161 deletions(-) diff --git a/frontend-grpc/FrontendGRpcSvc.cpp b/frontend-grpc/FrontendGRpcSvc.cpp index 2df229e411..7016e38b16 100644 --- a/frontend-grpc/FrontendGRpcSvc.cpp +++ b/frontend-grpc/FrontendGRpcSvc.cpp @@ -26,7 +26,32 @@ Status CtaRpcImpl::Version(::grpc::ServerContext *context, const ::google::proto return Status::OK; } -Status CtaRpcImpl::Archive(::grpc::ServerContext* context, const ::cta::frontend::rpc::ArchiveRequest* request, ::cta::frontend::rpc::ArchiveResponse* response) { +/* + * Validate the storage class and issue the archive ID which should be used for the Archive request + */ +Status CtaRpcImpl::Create(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::cta::frontend::rpc::CreateResponse* response) { + cta::log::LogContext lc(*m_log); + cta::log::ScopedParamContainer sp(lc); + + lc.log(cta::log::INFO, "Create"); + + try { + auto& instance = request->md().wf().instance().name(); + auto& storageClass = request->md().file().storage_class(); + cta::common::dataStructures::RequesterIdentity requester; + requester.name = request->md().cli().user().username(); + requester.group = request->md().cli().user().groupname(); + uint64_t archiveFileId = m_scheduler->checkAndGetNextArchiveFileId(instance, storageClass, requester, lc); + response->set_archive_file_id(archiveFileId); + } catch (cta::exception::Exception &ex) { + lc.log(cta::log::ERR, ex.getMessageValue()); + return ::grpc::Status(::grpc::StatusCode::INTERNAL, ex.getMessageValue()); + } + + return Status::OK; +} + +Status CtaRpcImpl::Archive(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::cta::frontend::rpc::ArchiveResponse* response) { cta::log::LogContext lc(*m_log); cta::log::ScopedParamContainer sp(lc); @@ -36,7 +61,7 @@ Status CtaRpcImpl::Archive(::grpc::ServerContext* context, const ::cta::frontend sp.add("remoteHost", context->peer()); sp.add("request", "archive"); - const std::string storageClass = request->file().storageclass(); + const std::string storageClass = request->md().file().storage_class(); if (storageClass.empty()) { return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Storage class is not set."); } @@ -44,65 +69,65 @@ Status CtaRpcImpl::Archive(::grpc::ServerContext* context, const ::cta::frontend lc.log(cta::log::DEBUG, "Archive request for storageClass: " + storageClass); cta::common::dataStructures::RequesterIdentity requester; - requester.name = request->cli().user().username(); - requester.group = request->cli().user().groupname(); + requester.name = request->md().cli().user().username(); + requester.group = request->md().cli().user().groupname(); // check validate request args - if (request->instance().name().empty()) { + if (request->md().wf().instance().name().empty()) { lc.log(cta::log::WARNING, "CTA instance is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA instance is not set."); } - if (request->cli().user().username().empty()) { + if (request->md().cli().user().username().empty()) { lc.log(cta::log::WARNING, "CTA username is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA username is not set."); } - if (request->cli().user().groupname().empty()) { + if (request->md().cli().user().groupname().empty()) { lc.log(cta::log::WARNING, "CTA groupname is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA groupname is not set."); } - if (!request->file().uid()) { + if (!request->md().file().owner().uid()) { lc.log(cta::log::WARNING, "File's owner uid can't be zero"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "File's owner uid can't be zero"); } - if (!request->file().gid()) { + if (!request->md().file().owner().gid()) { lc.log(cta::log::WARNING, "File's owner gid can't be zero"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "File's owner gid can't be zero"); } - if (request->file().path().empty()) { + if (request->md().file().lpath().empty()) { lc.log(cta::log::WARNING, "File's path can't be empty"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "File's path can't be empty"); } - auto instance = request->instance().name(); + auto instance = request->md().wf().instance().name(); sp.add("instance", instance); - sp.add("username", request->cli().user().username()); - sp.add("groupname", request->cli().user().groupname()); + sp.add("username", request->md().cli().user().username()); + sp.add("groupname", request->md().cli().user().groupname()); sp.add("storageClass", storageClass); - sp.add("fileID", request->file().fid()); + sp.add("fileID", request->md().file().disk_file_id()); try { - uint64_t archiveFileId = m_scheduler->checkAndGetNextArchiveFileId(instance, storageClass, requester, lc); + auto archiveFileId = request->md().file().archive_file_id(); sp.add("archiveID", archiveFileId); cta::common::dataStructures::ArchiveRequest archiveRequest; - cta::checksum::ProtobufToChecksumBlob(request->file().csb(), archiveRequest.checksumBlob); - archiveRequest.diskFileInfo.owner_uid = request->file().uid(); - archiveRequest.diskFileInfo.gid = request->file().gid(); - archiveRequest.diskFileInfo.path = request->file().path(); - archiveRequest.diskFileID = request->file().fid(); - archiveRequest.fileSize = request->file().size(); - archiveRequest.requester.name = request->cli().user().username(); - archiveRequest.requester.group = request->cli().user().groupname(); + cta::checksum::ProtobufToChecksumBlob(request->md().file().csb(), archiveRequest.checksumBlob); + archiveRequest.diskFileInfo.owner_uid = request->md().file().owner().uid(); + archiveRequest.diskFileInfo.gid = request->md().file().owner().gid(); + archiveRequest.diskFileInfo.path = request->md().file().lpath(); + archiveRequest.diskFileID = request->md().file().disk_file_id(); + archiveRequest.fileSize = request->md().file().size(); + archiveRequest.requester.name = request->md().cli().user().username(); + archiveRequest.requester.group = request->md().cli().user().groupname(); archiveRequest.storageClass = storageClass; - archiveRequest.srcURL = request->transport().dst_url(); - archiveRequest.archiveReportURL = request->transport().report_url() + "?archiveid=" + std::to_string(archiveFileId); - archiveRequest.archiveErrorReportURL = request->transport().error_report_url(); + archiveRequest.srcURL = request->md().transport().dst_url(); + archiveRequest.archiveReportURL = request->md().transport().report_url() + "?archiveid=" + std::to_string(archiveFileId); + archiveRequest.archiveErrorReportURL = request->md().transport().error_report_url(); archiveRequest.creationLog.host = context->peer(); archiveRequest.creationLog.username = instance; archiveRequest.creationLog.time = time(nullptr); @@ -114,19 +139,17 @@ Status CtaRpcImpl::Archive(::grpc::ServerContext* context, const ::cta::frontend + " archiveFileId: " + std::to_string(archiveFileId) + " RequestID: " + reqId); - response->set_fid(archiveFileId); - response->set_reqid(reqId); + response->set_objectstore_id(reqId); } catch (cta::exception::Exception &ex) { - lc.log(cta::log::CRIT, ex.getMessageValue()); + lc.log(cta::log::ERR, ex.getMessageValue()); return ::grpc::Status(::grpc::StatusCode::INTERNAL, ex.getMessageValue()); } return Status::OK; } - -Status CtaRpcImpl::Delete(::grpc::ServerContext* context, const ::cta::frontend::rpc::DeleteRequest* request, ::google::protobuf::Empty* response) { +Status CtaRpcImpl::Delete(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::google::protobuf::Empty* response) { cta::log::LogContext lc(*m_log); cta::log::ScopedParamContainer sp(lc); @@ -137,60 +160,60 @@ Status CtaRpcImpl::Delete(::grpc::ServerContext* context, const ::cta::frontend: sp.add("request", "delete"); // check validate request args - if (request->instance().name().empty()) { + if (request->md().wf().instance().name().empty()) { lc.log(cta::log::WARNING, "CTA instance is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA instance is not set."); } - if (request->cli().user().username().empty()) { + if (request->md().cli().user().username().empty()) { lc.log(cta::log::WARNING, "CTA username is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA username is not set."); } - if (request->cli().user().groupname().empty()) { + if (request->md().cli().user().groupname().empty()) { lc.log(cta::log::WARNING, "CTA groupname is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA groupname is not set."); } - if (request->archiveid() == 0) { + if (request->md().file().archive_file_id() == 0) { lc.log(cta::log::WARNING, "Invalid archive file id"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid archive file id."); } - if (!request->file().uid()) { + if (!request->md().file().owner().uid()) { lc.log(cta::log::WARNING, "File's owner uid can't be zero"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "File's owner uid can't be zero"); } - if (!request->file().gid()) { + if (!request->md().file().owner().gid()) { lc.log(cta::log::WARNING, "File's owner gid can't be zero"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "File's owner gid can't be zero"); } - if (request->file().path().empty()) { + if (request->md().file().lpath().empty()) { lc.log(cta::log::WARNING, "File's path can't be empty"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "File's path can't be empty"); } - auto instance = request->instance().name(); + auto instance = request->md().wf().instance().name(); // Unpack message cta::common::dataStructures::DeleteArchiveRequest deleteRequest; - deleteRequest.requester.name = request->cli().user().username(); - deleteRequest.requester.group = request->cli().user().groupname(); + deleteRequest.requester.name = request->md().cli().user().username(); + deleteRequest.requester.group = request->md().cli().user().groupname(); sp.add("instance", instance); - sp.add("username", request->cli().user().username()); - sp.add("groupname", request->cli().user().groupname()); - sp.add("fileID", request->file().fid()); + sp.add("username", request->md().cli().user().username()); + sp.add("groupname", request->md().cli().user().groupname()); + sp.add("fileID", request->md().file().disk_file_id()); - deleteRequest.diskFilePath = request->file().path(); - deleteRequest.diskFileId = request->file().fid(); + deleteRequest.diskFilePath = request->md().file().lpath(); + deleteRequest.diskFileId = request->md().file().disk_file_id(); deleteRequest.diskInstance = instance; // remove pending scheduler entry, if any - deleteRequest.archiveFileID = request->archiveid(); - if (!request->reqid().empty()) { - deleteRequest.address = request->reqid(); + deleteRequest.archiveFileID = request->md().file().archive_file_id(); + if (!request->objectstore_id().empty()) { + deleteRequest.address = request->objectstore_id(); } // Delete the file from the catalogue or from the objectstore if archive request is created @@ -207,8 +230,7 @@ Status CtaRpcImpl::Delete(::grpc::ServerContext* context, const ::cta::frontend: return Status::OK; } -Status CtaRpcImpl::Retrieve(::grpc::ServerContext* context, const ::cta::frontend::rpc::RetrieveRequest* request, ::cta::frontend::rpc::RetrieveResponse *response) { - +Status CtaRpcImpl::Retrieve(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::cta::frontend::rpc::RetrieveResponse* response) { cta::log::LogContext lc(*m_log); cta::log::ScopedParamContainer sp(lc); @@ -216,7 +238,7 @@ Status CtaRpcImpl::Retrieve(::grpc::ServerContext* context, const ::cta::fronten sp.add("remoteHost", context->peer()); sp.add("request", "retrieve"); - const std::string storageClass = request->file().storageclass(); + const std::string storageClass = request->md().file().storage_class(); if (storageClass.empty()) { return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Storage class is not set."); } @@ -224,67 +246,67 @@ Status CtaRpcImpl::Retrieve(::grpc::ServerContext* context, const ::cta::fronten lc.log(cta::log::DEBUG, "Retrieve request for storageClass: " + storageClass); // check validate request args - if (request->instance().name().empty()) { + if (request->md().wf().instance().name().empty()) { lc.log(cta::log::WARNING, "CTA instance is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA instance is not set."); } - if (request->cli().user().username().empty()) { + if (request->md().cli().user().username().empty()) { lc.log(cta::log::WARNING, "CTA username is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA username is not set."); } - if (request->cli().user().groupname().empty()) { + if (request->md().cli().user().groupname().empty()) { lc.log(cta::log::WARNING, "CTA groupname is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA groupname is not set."); } - if (request->archiveid() == 0) { + if (request->md().file().archive_file_id() == 0) { lc.log(cta::log::WARNING, "Invalid archive file id"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid archive file id."); } - if (!request->file().uid()) { + if (!request->md().file().owner().uid()) { lc.log(cta::log::WARNING, "File's owner uid can't be zero"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "File's owner uid can't be zero"); } - if (!request->file().gid()) { + if (!request->md().file().owner().gid()) { lc.log(cta::log::WARNING, "File's owner gid can't be zero"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "File's owner gid can't be zero"); } - if (request->file().path().empty()) { + if (request->md().file().lpath().empty()) { lc.log(cta::log::WARNING, "File's path can't be empty"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "File's path can't be empty"); } - auto instance = request->instance().name(); + auto instance = request->md().wf().instance().name(); sp.add("instance", instance); - sp.add("username", request->cli().user().username()); - sp.add("groupname", request->cli().user().groupname()); + sp.add("username", request->md().cli().user().username()); + sp.add("groupname", request->md().cli().user().groupname()); sp.add("storageClass", storageClass); - sp.add("archiveID", request->archiveid()); - sp.add("fileID", request->file().fid()); + sp.add("archiveID", request->md().file().archive_file_id()); + sp.add("fileID", request->md().file().disk_file_id()); // Unpack message cta::common::dataStructures::RetrieveRequest retrieveRequest; - retrieveRequest.requester.name = request->cli().user().username(); - retrieveRequest.requester.group = request->cli().user().groupname(); - retrieveRequest.dstURL = request->transport().dst_url(); - retrieveRequest.errorReportURL = request->transport().error_report_url(); - retrieveRequest.diskFileInfo.owner_uid = request->file().uid(); - retrieveRequest.diskFileInfo.gid = request->file().gid(); - retrieveRequest.diskFileInfo.path = request->file().path(); + retrieveRequest.requester.name = request->md().cli().user().username(); + retrieveRequest.requester.group = request->md().cli().user().groupname(); + retrieveRequest.dstURL = request->md().transport().dst_url(); + retrieveRequest.errorReportURL = request->md().transport().error_report_url(); + retrieveRequest.diskFileInfo.owner_uid = request->md().file().owner().uid(); + retrieveRequest.diskFileInfo.gid = request->md().file().owner().gid(); + retrieveRequest.diskFileInfo.path = request->md().file().lpath(); retrieveRequest.creationLog.host = context->peer(); retrieveRequest.creationLog.username = instance; retrieveRequest.creationLog.time = time(nullptr); retrieveRequest.isVerifyOnly = false; - retrieveRequest.archiveFileID = request->archiveid(); - sp.add("archiveID", request->archiveid()); - sp.add("fileID", request->file().fid()); + retrieveRequest.archiveFileID = request->md().file().archive_file_id(); + sp.add("archiveID", request->md().file().archive_file_id()); + sp.add("fileID", request->md().file().disk_file_id()); cta::utils::Timer t; @@ -296,7 +318,7 @@ Status CtaRpcImpl::Retrieve(::grpc::ServerContext* context, const ::cta::fronten + " archiveFileId: " + std::to_string(retrieveRequest.archiveFileID) + " RequestID: " + reqId); - response->set_reqid(reqId); + response->set_objectstore_id(reqId); } catch (cta::exception::Exception &ex){ lc.log(cta::log::CRIT, ex.getMessageValue()); return ::grpc::Status(::grpc::StatusCode::INTERNAL, ex.getMessageValue()); @@ -304,7 +326,7 @@ Status CtaRpcImpl::Retrieve(::grpc::ServerContext* context, const ::cta::fronten return Status::OK; } -Status CtaRpcImpl::CancelRetrieve(::grpc::ServerContext* context, const ::cta::frontend::rpc::CancelRetrieveRequest* request, ::google::protobuf::Empty* response) { +Status CtaRpcImpl::CancelRetrieve(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::google::protobuf::Empty* response) { cta::log::LogContext lc(*m_log); cta::log::ScopedParamContainer sp(lc); @@ -315,39 +337,39 @@ Status CtaRpcImpl::CancelRetrieve(::grpc::ServerContext* context, const ::cta::f sp.add("request", "cancel"); // check validate request args - if (request->instance().name().empty()) { + if (request->md().wf().instance().name().empty()) { lc.log(cta::log::WARNING, "CTA instance is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA instance is not set."); } - if (request->cli().user().username().empty()) { + if (request->md().cli().user().username().empty()) { lc.log(cta::log::WARNING, "CTA username is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA username is not set."); } - if (request->cli().user().groupname().empty()) { + if (request->md().cli().user().groupname().empty()) { lc.log(cta::log::WARNING, "CTA groupname is not set"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "CTA groupname is not set."); } - if (!request->archiveid()) { + if (!request->md().file().archive_file_id()) { lc.log(cta::log::WARNING, "Invalid archive file id"); return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid archive file id."); } - auto instance = request->instance().name(); + auto instance = request->md().wf().instance().name(); // Unpack message cta::common::dataStructures::CancelRetrieveRequest cancelRequest; - cancelRequest.requester.name = request->cli().user().username(); - cancelRequest.requester.group = request->cli().user().groupname(); - cancelRequest.archiveFileID = request->archiveid(); - cancelRequest.retrieveRequestId = request->reqid(); + cancelRequest.requester.name = request->md().cli().user().username(); + cancelRequest.requester.group = request->md().cli().user().groupname(); + cancelRequest.archiveFileID = request->md().file().archive_file_id(); + cancelRequest.retrieveRequestId = request->objectstore_id(); sp.add("instance", instance); - sp.add("username", request->cli().user().username()); - sp.add("groupname", request->cli().user().groupname()); - sp.add("fileID", request->archiveid()); - sp.add("schedulerJobID", request->reqid()); + sp.add("username", request->md().cli().user().username()); + sp.add("groupname", request->md().cli().user().groupname()); + sp.add("fileID", request->md().file().archive_file_id()); + sp.add("schedulerJobID", request->objectstore_id()); m_scheduler->abortRetrieve(instance, cancelRequest, lc); diff --git a/frontend-grpc/FrontendGRpcSvc.h b/frontend-grpc/FrontendGRpcSvc.h index 294f0f40cc..6a0d44ad16 100644 --- a/frontend-grpc/FrontendGRpcSvc.h +++ b/frontend-grpc/FrontendGRpcSvc.h @@ -28,11 +28,13 @@ private: public: CtaRpcImpl(cta::log::Logger *logger, std::unique_ptr<cta::catalogue::Catalogue> &catalogue, std::unique_ptr<cta::Scheduler> &scheduler); + // Archive/Retrieve interface + Status Create(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::cta::frontend::rpc::CreateResponse* response); + Status Archive(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::cta::frontend::rpc::ArchiveResponse* response); + Status Retrieve(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::cta::frontend::rpc::RetrieveResponse* response); + Status CancelRetrieve(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::google::protobuf::Empty* response); + Status Delete(::grpc::ServerContext* context, const ::cta::frontend::rpc::SchedulerRequest* request, ::google::protobuf::Empty* response); + + // Admin interface Status Version(::grpc::ServerContext *context, const ::google::protobuf::Empty *request, ::cta::admin::Version *response); - - Status Archive(::grpc::ServerContext* context, const ::cta::frontend::rpc::ArchiveRequest* request, ::cta::frontend::rpc::ArchiveResponse* response); - Status Retrieve(::grpc::ServerContext* context, const ::cta::frontend::rpc::RetrieveRequest* request, ::cta::frontend::rpc::RetrieveResponse* response); - Status Delete(::grpc::ServerContext* context, const ::cta::frontend::rpc::DeleteRequest* request, ::google::protobuf::Empty* response); - Status CancelRetrieve(::grpc::ServerContext* context, const ::cta::frontend::rpc::CancelRetrieveRequest* request, ::google::protobuf::Empty* response); }; - diff --git a/frontend-grpc/grpc-proto/protobuf/cta_grpc_frontend.proto b/frontend-grpc/grpc-proto/protobuf/cta_grpc_frontend.proto index d2ad36748f..9dbbb6a517 100644 --- a/frontend-grpc/grpc-proto/protobuf/cta_grpc_frontend.proto +++ b/frontend-grpc/grpc-proto/protobuf/cta_grpc_frontend.proto @@ -1,97 +1,90 @@ +/* + * @project The CERN Tape Archive (CTA) + * @copyright Copyright © 2021-2022 CERN + * @license This program is free software, distributed under the terms of the GNU General Public + * Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING". You can + * redistribute it and/or modify it under the terms of the GPL Version 3, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A + * PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * In applying this licence, CERN does not waive the privileges and immunities + * granted to it by virtue of its status as an Intergovernmental Organization or + * submit itself to any jurisdiction. + */ + syntax = "proto3"; option java_multiple_files = true; option java_package = "ch.cern.cta.rpc"; option optimize_for = CODE_SIZE; + package cta.frontend.rpc; import "google/protobuf/empty.proto"; - -import "cta_common.proto"; import "cta_admin.proto"; import "cta_eos.proto"; - -// -// gRPC interface to CTA frontend -// +import "cta_frontend.proto"; /* - * File metadata + * Requests sent to the CTA Frontend */ -message FileInfo { - string fid = 1; // disk system unique file ID - uint64 size = 2; // file size - string storageClass = 3; // tape system related storage class (file family) - cta.common.ChecksumBlob csb = 4; // set of knows checksums for the given file - uint32 uid = 5; // files owner user id - uint32 gid = 6; // files owner group id - string path = 7; // files path at creation time -} -/* - * Response to the ARCHIVE request. - */ -message ArchiveResponse { - uint64 fid = 1; // tape system unique file ID - string reqId = 2; // tape request scheduler ID, used to cancel the request +// gRPC Request for Archive/Retrieve/Delete/Cancel events +message SchedulerRequest { + cta.eos.Notification md = 1; //< Metadata associated with this request + string objectstore_id = 2; //< Address of the queued request in the SchedulerDB (objectstore), + //< used to cancel a previous PREPARE request + string client_version = 3; //< Client software version + string client_protobuf_version = 4; //< Client protobuf version } -/* - * Response to the RETRIEVE request. - */ -message RetrieveResponse { - string reqId = 1; // tape request scheduler ID, used to cancel the request +// gRPC Request for Admin commands +message AdminRequest { + cta.admin.AdminCmd admincmd = 1; //< CTA Admin Command + string client_version = 2; //< Version of cta-admin client + string client_protobuf_version = 3; //< Client protobuf version } - /* - * ARCHIVE request. + * Metadata responses returned by the CTA Frontend */ -message ArchiveRequest { - cta.common.Service instance = 1; // client instance ID - cta.eos.Client cli = 2; // requester information - cta.eos.Transport transport = 3; // IO, error and success endpoints - FileInfo file = 4; // files' metadata + +message CreateResponse { + uint64 archive_file_id = 1; //< CTA-assigned unique file ID } -/* - * RETRIEVE request. - */ -message RetrieveRequest { - cta.common.Service instance = 1; // client instance ID - cta.eos.Client cli = 2; // requester information - cta.eos.Transport transport = 3; // IO, error and success endpoints - FileInfo file = 4; // files' metadata - uint64 archiveId = 5; // tape system unique file ID +message ArchiveResponse { + string objectstore_id = 1; //< Address of the queued request in the SchedulerDB (objectstore), + //< used to cancel the request } -/* - * DELETE request. - */ -message DeleteRequest { - cta.common.Service instance = 1; // client instance ID - cta.eos.Client cli = 2; // requester information - FileInfo file = 3; // files' metadata - uint64 archiveId = 4; // tape system unique file ID - string reqId = 5; // pending ARCHIVE request scheduler ID +message RetrieveResponse { + string objectstore_id = 1; //< Address of the queued request in the SchedulerDB (objectstore), + //< used to cancel the request } /* - * CANCEL RETRIEVE request. + * gRPC request-response pairs */ -message CancelRetrieveRequest { - cta.common.Service instance = 1; // client instance ID - cta.eos.Client cli = 2; // requester information - uint64 archiveId = 3; // tape system unique file ID - string reqId = 4; // tape request scheduler ID, used to cancel the request -} service CtaRpc { - rpc Version (google.protobuf.Empty) returns (cta.admin.Version) {} + // Generic request to give a migration path from EOS + rpc GenericRequest (cta.xrd.Request) returns (cta.xrd.Response) {} + + // Specific request types + rpc Create (SchedulerRequest) returns (CreateResponse) {} + rpc Archive (SchedulerRequest) returns (ArchiveResponse) {} + rpc Retrieve (SchedulerRequest) returns (RetrieveResponse) {} + rpc Delete (SchedulerRequest) returns (google.protobuf.Empty) {} + rpc CancelRetrieve (SchedulerRequest) returns (google.protobuf.Empty) {} - rpc Archive (ArchiveRequest) returns (ArchiveResponse) {} - rpc Retrieve (RetrieveRequest) returns (RetrieveResponse) {} - rpc Delete (DeleteRequest) returns (google.protobuf.Empty) {} - rpc CancelRetrieve (CancelRetrieveRequest) returns (google.protobuf.Empty) {} + // Admin commands + rpc Admin (AdminRequest) returns (cta.xrd.Response) {} + + // Should possibly be replaced by AdminRequest "version" command + rpc Version (google.protobuf.Empty) returns (cta.admin.Version) {} +} -} \ No newline at end of file diff --git a/xrootd-ssi-protobuf-interface b/xrootd-ssi-protobuf-interface index 0d99b9180f..f05ac4849d 160000 --- a/xrootd-ssi-protobuf-interface +++ b/xrootd-ssi-protobuf-interface @@ -1 +1 @@ -Subproject commit 0d99b9180f83448e4e2dd9ff82d1cf0469e937e6 +Subproject commit f05ac4849d43590c459fe30bb834ef96eb515d7e -- GitLab