/* * This file is a part of the LinkAhead Project. * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> * Copyright (C) 2021-2024 IndiScale GmbH <info@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, 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 Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. * ********************************************************************************* * * This is derived work which is heavily based on * https://github.com/NeiRo21/grpcpp-bidi-streaming, Commit * cd9cb78e5d6d72806c2ec4c703e5e856b223dc96, Aug 10, 2020 * * The orginal work is licensed as * * > MIT License * > * > Copyright (c) 2019 NeiRo21 * > * > Permission is hereby granted, free of charge, to any person obtaining a * > copy of this software and associated documentation files (the "Software"), * > to deal in the Software without restriction, including without limitation * > the rights to use, copy, modify, merge, publish, distribute, sublicense, * > and/or sell copies of the Software, and to permit persons to whom the * > Software is furnished to do so, subject to the following conditions: * > * > The above copyright notice and this permission notice shall be included in * > all copies or substantial portions of the Software. * > * > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * > FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * > DEALINGS IN THE SOFTWARE. */ #ifndef CAOSDB_FILE_TRANSMISSION_DOWNLOAD_REQUEST_HANDLER_H #define CAOSDB_FILE_TRANSMISSION_DOWNLOAD_REQUEST_HANDLER_H #include "linkahead/file_descriptor.h" // for FileDescriptor #include "caosdb/entity/v1/main.pb.h" // for FileTransmissionS... #include "caosdb/entity/v1/main.grpc.pb.h" // for FileDownloadResponse #include "linkahead/file_transmission/file_writer.h" // for FileWriter #include "linkahead/handler_interface.h" // for HandlerTag, Handl... #include <cstdint> // for uint64_t #include <grpcpp/client_context.h> // for ClientContext #include <grpcpp/completion_queue.h> // for CompletionQueue #include <grpcpp/support/async_stream.h> // for ClientAsyncReader #include <grpcpp/support/status.h> // for Status #include <memory> // for unique_ptr namespace linkahead::transaction { using caosdb::entity::v1::FileDownloadRequest; using caosdb::entity::v1::FileDownloadResponse; using caosdb::entity::v1::FileTransmissionService; using linkahead::entity::FileDescriptor; using linkahead::transaction::HandlerInterface; using linkahead::transaction::HandlerTag; /* * Handler for the download request of a single file */ class DownloadRequestHandler final : public HandlerInterface { public: DownloadRequestHandler(HandlerTag tag, FileTransmissionService::Stub *stub, grpc::CompletionQueue *cq, FileDescriptor file_descriptor); ~DownloadRequestHandler() override = default; DownloadRequestHandler(const DownloadRequestHandler &) = delete; DownloadRequestHandler &operator=(const DownloadRequestHandler &) = delete; DownloadRequestHandler(DownloadRequestHandler &&) = delete; DownloadRequestHandler &operator=(DownloadRequestHandler &&) = delete; void Start() override { if (state_ == CallState::NewCall) { OnNext(true); } } bool OnNext(bool ok) override; void Cancel() override; protected: enum class CallState { NewCall, SendingRequest, ReceivingFile, CallComplete }; void handleNewCallState(); void handleSendingRequestState(); void handleReceivingFileState(); void handleCallCompleteState(); HandlerTag tag_; FileTransmissionService::Stub *stub_; grpc::CompletionQueue *cq_; grpc::ClientContext ctx_; std::unique_ptr<grpc::ClientAsyncReader<FileDownloadResponse>> rpc_; FileDownloadRequest *request_; FileDownloadResponse *response_; grpc::Status status_; CallState state_; std::unique_ptr<FileWriter> fileWriter_; FileDescriptor file_descriptor_; uint64_t bytesReceived_; }; } // namespace linkahead::transaction #endif