//------------------------------------------------------------------------------ //! @file ProcDirectoryBulkRequestDAO.hh //! @author Cedric Caffy - CERN //------------------------------------------------------------------------------ /************************************************************************ * EOS - the CERN Disk Storage System * * Copyright (C) 2017 CERN/Switzerland * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU 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 General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see .* ************************************************************************/ #ifndef EOS_PROCDIRECTORYBULKREQUESTDAO_HH #define EOS_PROCDIRECTORYBULKREQUESTDAO_HH #include "mgm/Namespace.hh" #include "mgm/bulk-request/dao/IBulkRequestDAO.hh" #include #include #include "mgm/bulk-request/dao/proc/ProcDirectoryBulkRequestLocations.hh" #include "mgm/bulk-request/dao/proc/ProcDirBulkRequestFile.hh" #include "mgm/bulk-request/prepare/CancellationBulkRequest.hh" EOSBULKNAMESPACE_BEGIN /** * This class is the bulk request persistency layer using the eos proc directory * * The bulk request persistence will be ensured by creating and listing a directory's extended attributes in a the /eos/.../proc/bulkrequest. */ class ProcDirectoryBulkRequestDAO : public IBulkRequestDAO, public eos::common::LogId { public: ProcDirectoryBulkRequestDAO(XrdMgmOfs* fileSystem, const ProcDirectoryBulkRequestLocations& mBulkRequestDirSchema); /** * Save the bulk request by updating the state (to CANCELLED) of a subset of files * belonging to a previously submitted stage bulk-request. * The files that are contained in the CancellationBulkRequest represent * the subset of files that needs to be cancelled on the Stage bulk-request * @param bulkRequest the bulkRequest that will be used to update the state * of the files located in a previously submitted stage request */ void saveBulkRequest(const CancellationBulkRequest* bulkRequest) override; /** * Save the bulk request by creating a directory in the /eos/.../proc/ directory and creating one extended attribute * per file in this directory: * - If a file in the bulk-request exists, the file will be named according to the fileId * - If a file in the bulk-request does not exist, the file will be named according to the path provided in the format like the one in the EOS * recycle-bin (each '/' will be replaced by "#:#") * @param bulkRequest the BulkRequest to save */ void saveBulkRequest(const StageBulkRequest* bulkRequest) override; /** * Get the bulk-request from the /eos/.../proc directory * @param id the id of the bulk-request * @param type the type of bulk-request * @return the bulk-request associated to the id and the type, nullptr if it does not exist */ std::unique_ptr getBulkRequest(const std::string& id, const BulkRequest::Type& type) override; /** * Delete all the bulk-request of a certain type that were not accessed for hours * @param type the bulk-request type to look for * @param seconds the number of seconds after which the bulk-requests can be deleted if they were not queried * @returns the number of deleted bulk-request */ uint64_t deleteBulkRequestNotQueriedFor(const BulkRequest::Type& type, const std::chrono::seconds& seconds) override; /** * Returns true if the bulk-request corresponding to the id and the type * passed in parameters exists, false otherwise * @param bulkRequestId the id of the bulk-request to check * @param type the type of the bulk-request to test * @returns true if the bulk-request exists, false otherwise */ bool exists(const std::string& bulkRequestId, const BulkRequest::Type& type) override; /** * Deletes the bulk-request passed in parameters from the persistency * @param bulkRequest the bulk-request to delete */ void deleteBulkRequest(const BulkRequest* bulkRequest) override; virtual ~ProcDirectoryBulkRequestDAO() {} private: //Interface to the EOS filesystem to allow the creation of files and directories XrdMgmOfs* mFileSystem; const ProcDirectoryBulkRequestLocations& mProcDirectoryBulkRequestLocations; eos::common::VirtualIdentity mVid; const char* LAST_ACCESS_TIME_XATTR_NAME = "last_accessed_time"; inline static const std::string ISSUER_UID_XATTR_NAME = "issuer_uid"; //File persisted as bulk-request's directory extended attribute will be prefixed by this prefix inline static const std::string FILE_ID_XATTR_KEY_PREFIX = "fid."; inline static const std::string CREATION_TIME_XATTR_NAME = "creation_time"; void cancelStageBulkRequest(const CancellationBulkRequest* bulkRequest); /** * Creates a directory to store the bulk-request files within it * @param bulkRequest the bulkRequest to get the id from * @param bulkReqProcPath the directory in /proc/ where the files contained in the bulk-request will be saved */ void createBulkRequestDirectory(const BulkRequest* bulkRequest, const std::string& bulkReqProcPath); /** * Generate the bulk-request directory path within the /eos/.../proc/ directory * It is generated according to the id of the bulk-request * @param bulkRequest the bulk-request to generate the path from * @return the string containing the path of the directory used to store the bulk-request */ std::string generateBulkRequestProcPath(const BulkRequest* bulkRequest); /** * Generate the bulk-request directory path within the /eos/.../proc/ directory * It is generated according to the id of the bulk-request * @param bulkRequestId the id of the bulk-request to generate the proc directory path * @param type the type of the bulk-request to generate the proc directory path * @return the string containing the path of the directory used to store the bulk-request */ std::string generateBulkRequestProcPath(const std::string& bulkRequestId, const BulkRequest::Type& type); /** * Insert the files contained in the bulk request into the directory created by createBulkRequestDirectory() * @param bulkRequest the bulk-request containing the files to insert in the directory * @param bulkReqProcPath the he directory in /proc/ where the files contained in the bulk-request will be saved */ //void insertBulkRequestFilesToBulkRequestDirectory(const BulkRequest * bulkRequest, const std::string & bulkReqProcPath); /** * Performs the cleaning of the bulk-request directory if an exception happens during the persistency of the bulk-request * @param bulkReqProcPath the directory where the bulk-request should have been stored */ void cleanAfterExceptionHappenedDuringBulkRequestSave(const std::string& bulkReqProcPath) noexcept; /** * Deletes the directory located in the path passed in parameter * @param path the path of the directory to delete */ void deleteDirectory(const std::string& path); /** * Returns true if the directory path passed in parameter exists, false otherwise * @param dirPath the path of the directory to check its existence * @return true if the directory path passed in parameter exists, false otherwise */ bool existsAndIsDirectory(const std::string& dirPath); /** * creates the bulk request and fills it from the directory passed in parameter * @param bulkRequest the bulkRequest to fill * @param xattrs the extended attributes of the directory where the bulk-request is persisted * @param bulkRequestProcPath the path where the bulk request is persisted */ void fillBulkRequestFromXattrs(bulk::BulkRequest* bulkRequest, const eos::IContainerMD::XAttrMap& xattrs); std::unique_ptr initializeStageBulkRequestFromXattrs( const std::string& requestId, const eos::IContainerMD::XAttrMap& xattrs); /** * Fills the directoryContent map passed in parameter. The key is the full path of the directory given in parameter * the value is the file names that are located in the directory. * Reminder: the files that are in the directory of the bulk-request are the fileIds of the files that were submitted with the bulk-request (or * transformed paths for the files that were submitted did not exist) * @param path the path of the directory to get the content * @param directoryContent the map that will be filled with the content of the directory passed in parameter */ void getDirectoryContent(const std::string& path, std::map>& directoryContent); /** * Fills the xattrs map with the extended attributes of the file/directory whose path is passed in parameter * @param path the path of the file to get the extended attributes from * @param xattrs extended attributes map to fill */ void fetchExtendedAttributes(const std::string& path, eos::IContainerMD::XAttrMap& xattrs); /** * Asynchronously fetch the file metadata by using the eosFileService->getFileMDFut() method. The filesWithFuture map will * be filled by this method * @param file the file to asynchronously fetch the metadata * @param filesWithFuture the map to include the file and its future */ void initiateFileMDFetch(const ProcDirBulkRequestFile& file, std::map>& filesWithFuture); /** * Wait for the futures associated to the files inserted in the filesWithFuture map (got filled by the initiateFileMDFetch() method). * Once all the futures have returned * @param filesWithFuture the map containing the files and the associated future to get the metadata from it * @param bulkRequest the bulk request in which the files will be added */ void getFilesPathAndAddToBulkRequest( std::map>& filesWithFuture, BulkRequest* bulkRequest); /** * Sets an extended attribute on the file whose path is passed in parameter * @param path the path of the file or directory to set the extended attribute * @param xattrName the extended attribute name * @param xattrValue the extended attribute value */ void setExtendedAttribute(const std::string& path, const std::string& xattrName, const std::string& xattrValue); /** * Set the last_access_time extended attribute to the current timestamp on the file/directory passed in parameter * @param path the path of the file/directory to set the last acess time */ void updateLastAccessTime(const std::string& path); /** * Generate the extended attributes map that will be added to the bulk-request directory * @param bulkRequest the bulk-request from which the map will be added * @param xattrs the map containing the fid of a file associated to an eventual error (e.g prepare submission) */ void generateXattrsMapFromBulkRequest(const BulkRequest* bulkRequest, eos::IContainerMD::XAttrMap& xattrs); void generateXattrsMapFromBulkRequest(const StageBulkRequest* bulkRequest, eos::IContainerMD::XAttrMap& xattrs); /** * Persist the bulk-request in the extended attributes of the directory * @param directoryBulkReqPath the directory where each file belonging to the bulk-request will be persisted * @param xattrs the map containing each file belonging to the bulk-request */ void persistBulkRequestDirectory(const std::string& directoryBulkReqPath, const eos::IContainerMD::XAttrMap& xattrs); }; EOSBULKNAMESPACE_END #endif // EOS_PROCDIRECTORYBULKREQUESTDAO_HH