diff --git a/src/XrdApps.cmake b/src/XrdApps.cmake index cb6704818cc..ffab00f39f8 100644 --- a/src/XrdApps.cmake +++ b/src/XrdApps.cmake @@ -5,6 +5,7 @@ #------------------------------------------------------------------------------- set( LIB_XRDCL_PROXY_PLUGIN XrdClProxyPlugin-${PLUGIN_VERSION} ) set( LIB_XRDCL_RECORDER_PLUGIN XrdClRecorder-${PLUGIN_VERSION} ) +set( LIB_XRDCL_JCACHE_PLUGIN XrdClJCachePlugin-${PLUGIN_VERSION} ) #------------------------------------------------------------------------------- # Shared library version @@ -202,11 +203,23 @@ target_link_libraries( XrdCl XrdUtils ) +#------------------------------------------------------------------------------- +# XrdClJCachePlugin library +#------------------------------------------------------------------------------- +add_library( + ${LIB_XRDCL_JCACHE_PLUGIN} + MODULE + XrdApps/XrdClJCachePlugin/XrdClJCachePlugin.cc + XrdApps/XrdClJCachePlugin/XrdClJCacheFile.cc) + +target_link_libraries(${LIB_XRDCL_JCACHE_PLUGIN} PRIVATE XrdCl) + + #------------------------------------------------------------------------------- # Install #------------------------------------------------------------------------------- install( - TARGETS XrdAppUtils ${LIB_XRDCL_PROXY_PLUGIN} ${LIB_XRDCL_RECORDER_PLUGIN} + TARGETS XrdAppUtils ${LIB_XRDCL_PROXY_PLUGIN} ${LIB_XRDCL_RECORDER_PLUGIN} ${LIB_XRDCL_JCACHE_PLUGIN} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) diff --git a/src/XrdApps/XrdClJCachePlugin/CMakeLists.txt b/src/XrdApps/XrdClJCachePlugin/CMakeLists.txt new file mode 100644 index 00000000000..5c3a1e52302 --- /dev/null +++ b/src/XrdApps/XrdClJCachePlugin/CMakeLists.txt @@ -0,0 +1,37 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2024 by European Organization for Nuclear Research (CERN) +// Author: Andreas-Joachim Peters +//------------------------------------------------------------------------------ +// This file is part of the XRootD software suite. +// +// XRootD is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// XRootD 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 Lesser General Public License +// along with XRootD. If not, see . +// +// 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. + +add_library(XrdClJCacheClient MODULE + XrdCLJCachePlugin.cc XrdClJCachePlugin.hh + XrdClJCacheFile.cc XrdClJCacheFile.hh) + +set_target_properties(XrdClJCacheClient PROPERTIES + VERSION ${VERSION} + SOVERSION ${VERSION_MAJOR} + MACOSX_RPATH TRUE) + +install(TARGETS XrdClJCacheClient + LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}) + diff --git a/src/XrdApps/XrdClJCachePlugin/XrdClJCacheFile.cc b/src/XrdApps/XrdClJCachePlugin/XrdClJCacheFile.cc new file mode 100644 index 00000000000..779a1c122b0 --- /dev/null +++ b/src/XrdApps/XrdClJCachePlugin/XrdClJCacheFile.cc @@ -0,0 +1,311 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2024 by European Organization for Nuclear Research (CERN) +// Author: Andreas-Joachim Peters +//------------------------------------------------------------------------------ +// This file is part of the XRootD software suite. +// +// XRootD is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// XRootD 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 Lesser General Public License +// along with XRootD. If not, see . +// +// 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. + +/*----------------------------------------------------------------------------*/ +#include "XrdClJCacheFile.hh" +/*----------------------------------------------------------------------------*/ + +std::string JCacheFile::sCachePath=""; + +//------------------------------------------------------------------------------ +// Constructor +//------------------------------------------------------------------------------ +JCacheFile::JCacheFile(): + mIsOpen(false), + pFile(0) +{ +} + + +//------------------------------------------------------------------------------ +// Destructor +//------------------------------------------------------------------------------ +JCacheFile::~JCacheFile() +{ + + if (pFile) { + delete pFile; + } +} + + +//------------------------------------------------------------------------------ +// Open +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::Open(const std::string& url, + OpenFlags::Flags flags, + Access::Mode mode, + ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (mIsOpen) { + st = XRootDStatus(stError, errInvalidOp); + return st; + } + + pFile = new XrdCl::File(false); + st = pFile->Open(url, flags, mode, handler, timeout); + + if (st.IsOK()) { + mIsOpen = true; + } + + + if ((flags & OpenFlags::Flags::Read) == OpenFlags::Flags::Read) { + // attach to a cache + } + + return st; +} + + +//------------------------------------------------------------------------------ +// Close +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::Close(ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (mIsOpen) { + mIsOpen = false; + + if (pFile) { + st = pFile->Close(handler, timeout); + } + } else { + // File already closed + st = XRootDStatus(stError, errInvalidOp); + XRootDStatus* ret_st = new XRootDStatus(st); + handler->HandleResponse(ret_st, 0); + } + + return st; +} + + +//------------------------------------------------------------------------------ +// Stat +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::Stat(bool force, + ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (pFile) { + st = pFile->Stat(force, handler, timeout); + } else { + st = XRootDStatus(stError, errInvalidOp); + } + + return st; +} + + +//------------------------------------------------------------------------------ +// Read +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::Read(uint64_t offset, + uint32_t size, + void* buffer, + ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (pFile) { + st = pFile->Read(offset, size, buffer, handler, timeout); + } else { + st = XRootDStatus(stError, errInvalidOp); + } + return st; +} + + +//------------------------------------------------------------------------------ +// Write +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::Write(uint64_t offset, + uint32_t size, + const void* buffer, + ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (pFile) { + st = pFile->Write(offset, size, buffer, handler, timeout); + } else { + st = XRootDStatus(stError, errInvalidOp); + } + + return st; +} + + +//------------------------------------------------------------------------------ +// Sync +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::Sync(ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (pFile) { + st = pFile->Sync(handler, timeout); + } else { + st = XRootDStatus(stError, errInvalidOp); + } + + return st; +} + + +//------------------------------------------------------------------------------ +// Truncate +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::Truncate(uint64_t size, + ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (pFile) { + st = pFile->Truncate(size, handler, timeout); + } else { + st = XRootDStatus(stError, errInvalidOp); + } + + return st; +} + + +//------------------------------------------------------------------------------ +// VectorRead +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::VectorRead(const ChunkList& chunks, + void* buffer, + ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (pFile) { + st = pFile->VectorRead(chunks, buffer, handler, timeout); + } else { + st = XRootDStatus(stError, errInvalidOp); + } + + return st; +} + + +//------------------------------------------------------------------------------ +// Fcntl +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::Fcntl(const XrdCl::Buffer& arg, + ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (pFile) { + st = pFile->Fcntl(arg, handler, timeout); + } else { + st = XRootDStatus(stError, errInvalidOp); + } + + return st; +} + + +//------------------------------------------------------------------------------ +// Visa +//------------------------------------------------------------------------------ +XRootDStatus +JCacheFile::Visa(ResponseHandler* handler, + uint16_t timeout) +{ + XRootDStatus st; + + if (pFile) { + st = pFile->Visa(handler, timeout); + } else { + st = XRootDStatus(stError, errInvalidOp); + } + + return st; +} + + +//------------------------------------------------------------------------------ +// IsOpen +//------------------------------------------------------------------------------ +bool +JCacheFile::IsOpen() const +{ + return mIsOpen; +} + + +//------------------------------------------------------------------------------ +// @see XrdCl::File::SetProperty +//------------------------------------------------------------------------------ +bool +JCacheFile::SetProperty(const std::string& name, + const std::string& value) +{ + if (pFile) { + return pFile->SetProperty(name, value); + } else { + return false; + } +} + + +//------------------------------------------------------------------------------ +// @see XrdCl::File::GetProperty +//------------------------------------------------------------------------------ +bool +JCacheFile::GetProperty(const std::string& name, + std::string& value) const +{ + if (pFile) { + return pFile->GetProperty(name, value); + } else { + return false; + } +} + diff --git a/src/XrdApps/XrdClJCachePlugin/XrdClJCacheFile.hh b/src/XrdApps/XrdClJCachePlugin/XrdClJCacheFile.hh new file mode 100644 index 00000000000..ea4c7ef437c --- /dev/null +++ b/src/XrdApps/XrdClJCachePlugin/XrdClJCacheFile.hh @@ -0,0 +1,174 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2024 by European Organization for Nuclear Research (CERN) +// Author: Andreas-Joachim Peters +//------------------------------------------------------------------------------ +// This file is part of the XRootD software suite. +// +// XRootD is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// XRootD 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 Lesser General Public License +// along with XRootD. If not, see . +// +// 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. + +#pragma once + +/*----------------------------------------------------------------------------*/ +#include "XrdCl/XrdClPlugInInterface.hh" +/*----------------------------------------------------------------------------*/ + +using namespace XrdCl; + +//---------------------------------------------------------------------------- +//! RAIN file plugin +//---------------------------------------------------------------------------- +class JCacheFile: public XrdCl::FilePlugIn +{ +public: + + //---------------------------------------------------------------------------- + //! Constructor + //---------------------------------------------------------------------------- + JCacheFile(); + + + //---------------------------------------------------------------------------- + //! Destructor + //---------------------------------------------------------------------------- + virtual ~JCacheFile(); + + + //---------------------------------------------------------------------------- + //! Open + //---------------------------------------------------------------------------- + virtual XRootDStatus Open(const std::string& url, + OpenFlags::Flags flags, + Access::Mode mode, + ResponseHandler* handler, + uint16_t timeout); + + + //---------------------------------------------------------------------------- + //! Close + //---------------------------------------------------------------------------- + virtual XRootDStatus Close(ResponseHandler* handler, + uint16_t timeout); + + + //---------------------------------------------------------------------------- + //! Stat + //---------------------------------------------------------------------------- + virtual XRootDStatus Stat(bool force, + ResponseHandler* handler, + uint16_t timeout); + + + //---------------------------------------------------------------------------- + //! Read + //---------------------------------------------------------------------------- + virtual XRootDStatus Read(uint64_t offset, + uint32_t size, + void* buffer, + ResponseHandler* handler, + uint16_t timeout); + + + //---------------------------------------------------------------------------- + //! Write + //---------------------------------------------------------------------------- + virtual XRootDStatus Write(uint64_t offset, + uint32_t size, + const void* buffer, + ResponseHandler* handler, + uint16_t timeout); + + + //---------------------------------------------------------------------------- + //! Sync + //---------------------------------------------------------------------------- + virtual XRootDStatus Sync(ResponseHandler* handler, + uint16_t timeout); + + + //---------------------------------------------------------------------------- + //! Truncate + //---------------------------------------------------------------------------- + virtual XRootDStatus Truncate(uint64_t size, + ResponseHandler* handler, + uint16_t timeout); + + + //---------------------------------------------------------------------------- + //! VectorRead + //---------------------------------------------------------------------------- + virtual XRootDStatus VectorRead(const ChunkList& chunks, + void* buffer, + ResponseHandler* handler, + uint16_t timeout); + + + //------------------------------------------------------------------------ + //! Fcntl + //------------------------------------------------------------------------ + virtual XRootDStatus Fcntl(const Buffer& arg, + ResponseHandler* handler, + uint16_t timeout); + + + //---------------------------------------------------------------------------- + //! Visa + //---------------------------------------------------------------------------- + virtual XRootDStatus Visa(ResponseHandler* handler, + uint16_t timeout); + + + //---------------------------------------------------------------------------- + //! IsOpen + //---------------------------------------------------------------------------- + virtual bool IsOpen() const; + + + //---------------------------------------------------------------------------- + //! @see XrdCl::File::SetProperty + //---------------------------------------------------------------------------- + virtual bool SetProperty(const std::string& name, + const std::string& value); + + + //---------------------------------------------------------------------------- + //! @see XrdCl::File::GetProperty + //---------------------------------------------------------------------------- + virtual bool GetProperty(const std::string& name, + std::string& value) const; + + + //---------------------------------------------------------------------------- + //! validate the local cache + //---------------------------------------------------------------------------- + inline bool IsValid() + { + return true; + } + + //---------------------------------------------------------------------------- + //! set the local cache path + //---------------------------------------------------------------------------- + + static void SetCache(const std::string& path) { sCachePath = path; } + + static std::string sCachePath; +private: + bool mIsOpen; + XrdCl::File* pFile; +}; + diff --git a/src/XrdApps/XrdClJCachePlugin/XrdClJCachePlugin.cc b/src/XrdApps/XrdClJCachePlugin/XrdClJCachePlugin.cc new file mode 100644 index 00000000000..85f2a93b319 --- /dev/null +++ b/src/XrdApps/XrdClJCachePlugin/XrdClJCachePlugin.cc @@ -0,0 +1,38 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2024 by European Organization for Nuclear Research (CERN) +// Author: Andreas-Joachim Peters +//------------------------------------------------------------------------------ +// This file is part of the XRootD software suite. +// +// XRootD is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// XRootD 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 Lesser General Public License +// along with XRootD. If not, see . +// +// 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. +//------------------------------------------------------------------------------ + +#include "XrdClJCachePlugin.hh" + +XrdVERSIONINFO(XrdClGetPlugIn, XrdClGetPlugIn) + +extern "C" +{ + void* XrdClGetPlugIn( const void* arg ) + { + const std::map* config = + static_cast< const std::map* >(arg); + return static_cast(new XrdCl::JCacheFactory( config ) ); + } +} + diff --git a/src/XrdApps/XrdClJCachePlugin/XrdClJCachePlugin.hh b/src/XrdApps/XrdClJCachePlugin/XrdClJCachePlugin.hh new file mode 100644 index 00000000000..aaf80e8a492 --- /dev/null +++ b/src/XrdApps/XrdClJCachePlugin/XrdClJCachePlugin.hh @@ -0,0 +1,81 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2024 by European Organization for Nuclear Research (CERN) +// Author: Andreas-Joachim Peters +//------------------------------------------------------------------------------ +// This file is part of the XRootD software suite. +// +// XRootD is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// XRootD 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 Lesser General Public License +// along with XRootD. If not, see . +// +// 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. + +#pragma once +#include "XrdCl/XrdClPlugInInterface.hh" +#include "XrdClJCacheFile.hh" +#include "XrdCl/XrdClDefaultEnv.hh" +#include "XrdCl/XrdClLog.hh" + +namespace XrdCl +{ +//------------------------------------------------------------------------------ +//! XrdCl JCache plug-in factory +//------------------------------------------------------------------------------ +class JCacheFactory : public PlugInFactory +{ + public: + //---------------------------------------------------------------------------- + //! Constructor + //! + //! @param config map containing configuration parameters + //---------------------------------------------------------------------------- + JCacheFactory( const std::map* config ) + { + if( config ) + { + auto itr = config->find( "cache" ); + JCacheFile::SetCache( itr != config->end() ? itr->second : "" ); + } + } + + //---------------------------------------------------------------------------- + //! Destructor + //---------------------------------------------------------------------------- + virtual ~JCacheFactory() + { + } + + //---------------------------------------------------------------------------- + //! Create a file plug-in for the given URL + //---------------------------------------------------------------------------- + virtual FilePlugIn* CreateFile(const std::string& url) + { + std::unique_ptr ptr( new JCacheFile() ); + if( !ptr->IsValid() ) + return nullptr; + return static_cast( ptr.release() ); + } + + //---------------------------------------------------------------------------- + //! Create a file system plug-in for the given URL + //---------------------------------------------------------------------------- + virtual FileSystemPlugIn* CreateFileSystem(const std::string& url) + { + Log* log = DefaultEnv::GetLog(); + log->Error(1, "FileSystem plugin implementation not supported"); + return static_cast(0); + } +}; + +} // namespace XrdCl diff --git a/src/XrdVersionPlugin.hh b/src/XrdVersionPlugin.hh index 121949e6826..5c768b9f592 100644 --- a/src/XrdVersionPlugin.hh +++ b/src/XrdVersionPlugin.hh @@ -179,6 +179,7 @@ "libXrdBwm.so", \ "libXrdCksCalczcrc32.so", \ "libXrdClProxyPlugin.so", \ + "libXrdClJCachePlugin.so", \ "libXrdCmsRedirectLocal.so", \ "libXrdCryptossl.so", \ "libXrdHttp.so", \