The Gaudi Framework  master (37c0b60a)
MultiFileCatalog.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 #include "MultiFileCatalog.h"
12 #include "createGuidAsString.h"
13 #include <Gaudi/PluginService.h>
14 #include <GaudiKernel/MsgStream.h>
15 #include <GaudiKernel/strcasecmp.h>
16 #include <algorithm>
17 #include <functional>
18 #include <stdexcept>
19 
20 using namespace Gaudi;
21 using namespace std;
22 
23 namespace {
24  template <typename C, typename F>
25  F for_each( C& c, F&& f ) {
26  return std::for_each( std::begin( c ), std::end( c ), std::forward<F>( f ) );
27  }
28 } // namespace
29 
31 
32 // ----------------------------------------------------------------------------
34  if ( !Service::initialize().isSuccess() ) {
35  printError( "Failed to initialize service base class.", false );
36  return StatusCode::SUCCESS;
37  }
38  std::string current;
39  try {
40  for ( const auto& i : m_catalogNames ) {
41  current = i;
42  addCatalog( i );
43  }
44  init();
45  return StatusCode::SUCCESS;
46  } catch ( const std::exception& /* e */ ) { printError( "Cannot add file catalog:" + current, false ); }
47  return StatusCode::FAILURE;
48 }
49 // ----------------------------------------------------------------------------
51  commit();
52  for_each( m_catalogs, []( IFileCatalog* i ) { i->release(); } );
53  m_catalogs.clear();
54  m_started = false;
55  return Service::finalize();
56 }
57 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62  static const string s( "MultiCatalog" );
63  return s;
64 }
65 // ----------------------------------------------------------------------------
66 IFileCatalog* MultiFileCatalog::getCatalog( CSTR fid, bool throw_if_not, bool writable, bool prt ) const {
67  for ( const auto& c : m_catalogs ) {
68  if ( !c || ( writable && c->readOnly() ) ) continue;
69  if ( fid.empty() || ( !fid.empty() && c->existsFID( fid ) ) ) return c;
70  }
71  if ( prt ) {
72  printError( "No writable file catalog found which contains FID:" + fid, throw_if_not );
73  } else {
74  debug() << "No writable file catalog found which contains FID:" << fid << endmsg;
75  }
76  return nullptr;
77 }
78 // ----------------------------------------------------------------------------
79 IFileCatalog* MultiFileCatalog::findCatalog( CSTR connect, bool must_be_writable ) const {
80  auto i = std::find_if( m_catalogs.begin(), m_catalogs.end(),
81  [&]( const IFileCatalog* f ) { return connect == f->connectInfo(); } );
82  return ( i != m_catalogs.end() && ( !must_be_writable || !( *i )->readOnly() ) ) ? *i : nullptr;
83 }
84 // ----------------------------------------------------------------------------
85 MultiFileCatalog::Catalogs::iterator MultiFileCatalog::i_findCatalog( CSTR connect, bool must_be_writable ) {
86  auto i = std::find_if( m_catalogs.begin(), m_catalogs.end(),
87  [&]( const IFileCatalog* f ) { return connect == f->connectInfo(); } );
88  if ( i != m_catalogs.end() && must_be_writable && ( *i )->readOnly() ) { i = m_catalogs.end(); }
89  return i;
90 }
91 // ----------------------------------------------------------------------------
92 void MultiFileCatalog::printError( CSTR msg, bool rethrow ) const {
93  if ( rethrow ) {
94  fatal() << msg << endmsg;
95  throw runtime_error( "Catalog> " + msg );
96  }
97  error() << msg << endmsg;
98 }
99 // ----------------------------------------------------------------------------
101  if ( !con.empty() ) {
102  if ( !findCatalog( con, false ) ) {
103  static const string xml_typ = "Gaudi::XMLFileCatalog";
104  auto id0 = con.find( "_" );
105  string typ = con.substr( 0, id0 );
106  string url = con.substr( id0 + 1 );
107  IInterface* cat = nullptr;
108  if ( strncasecmp( "xml", typ.c_str(), 3 ) == 0 ) {
109  cat = IFileCatalog::Factory::create( xml_typ, url, msgSvc().get() ).release();
110  } else {
111  using Gaudi::PluginService::Details::Registry;
112  Registry& registry = Registry::instance();
113  if ( registry.getInfo( typ ).factory.type() == typeid( Service::Factory::FactoryType ) ) {
114  cat = Service::Factory::create( typ, url, serviceLocator().get() ).release();
115  } else if ( registry.getInfo( typ ).factory.type() == typeid( IFileCatalog::Factory::FactoryType ) ) {
116  cat = IFileCatalog::Factory::create( typ, url, msgSvc().get() ).release();
117  }
118  }
119  if ( cat ) {
120  auto fileCat = SmartIF<IFileCatalog>( cat );
121  if ( fileCat ) {
122  addCatalog( fileCat.get() ); // addCatalog will take care of the refCount of fileCat...
123  return;
124  }
125  }
126  printError( "Failed to create catalog connection:" + con, true );
127  }
129  return;
130  }
131  printError( "Got invalid (empty) catalog connection string.", true );
132 }
133 // ----------------------------------------------------------------------------
135  if ( cat ) {
136  cat->addRef();
137  m_catalogs.push_back( cat );
138  return;
139  }
140  printError( "Got invalid catalog to be added to multi catalog.", true );
141 }
142 // ----------------------------------------------------------------------------
144  if ( con.empty() || con == "*" ) {
145  for_each( m_catalogs, []( IFileCatalog* i ) { i->release(); } );
146  m_catalogs.clear();
147  return;
148  }
149  removeCatalog( findCatalog( con, false ) );
150 }
151 // ----------------------------------------------------------------------------
153  if ( cat ) {
154  auto i = find( m_catalogs.begin(), m_catalogs.end(), cat );
155  if ( i != m_catalogs.end() ) {
156  ( *i )->release();
157  m_catalogs.erase( i );
158  return;
159  }
160  printError( "Unknown file catalog -- cannot be removed.", true );
161  }
162  printError( "Invalid file catalog.", true );
163 }
164 // ----------------------------------------------------------------------------
166  if ( cat ) {
167  if ( !cat->readOnly() ) {
168  auto i = find( m_catalogs.begin(), m_catalogs.end(), cat );
169  if ( i != m_catalogs.end() ) {
170  m_catalogs.erase( i );
171  m_catalogs.insert( m_catalogs.begin(), cat );
172  return;
173  }
174  printError( "The catalog " + cat->connectInfo() + " is not known.", true );
175  }
176  printError( "The catalog " + cat->connectInfo() + " is not writable.", true );
177  }
178  printError( "Invalid file catalog.", true );
179 }
180 // ----------------------------------------------------------------------------
182  auto i = i_findCatalog( connect, true );
183  if ( i == m_catalogs.end() ) {
184  addCatalog( connect );
185  setWriteCatalog( findCatalog( connect, true ) );
186  return;
187  }
188  setWriteCatalog( *i );
189 }
190 // ----------------------------------------------------------------------------
191 string MultiFileCatalog::getMetaDataItem( CSTR fid, CSTR attr ) const {
192  std::string result;
193  for ( const auto& i : m_catalogs ) {
194  result = i->getMetaDataItem( fid, attr );
195  if ( !result.empty() ) break;
196  }
197  return result;
198 }
200 void MultiFileCatalog::registerPFN( CSTR fid, CSTR pfn, CSTR ftype ) const {
201  IFileCatalog* c = getCatalog( fid, false, true, false );
202  if ( !c ) c = getCatalog( "", true, true, true );
203  c->registerPFN( fid, pfn, ftype );
204 }
206 void MultiFileCatalog::registerLFN( CSTR fid, CSTR lfn ) const {
207  IFileCatalog* c = getCatalog( fid, false, true, false );
208  if ( !c ) c = getCatalog( "", true, true, true );
209  c->registerLFN( fid, lfn );
210 }
211 // ----------------------------------------------------------------------------
213  return std::all_of( std::begin( m_catalogs ), std::end( m_catalogs ),
214  []( const IFileCatalog* i ) { return i->readOnly(); } );
215 }
216 // ----------------------------------------------------------------------------
218  return std::any_of( std::begin( m_catalogs ), std::end( m_catalogs ),
219  []( const IFileCatalog* i ) { return i->dirty(); } );
220 }
221 // ----------------------------------------------------------------------------
223  for_each( m_catalogs, []( IFileCatalog* i ) { i->init(); } );
224  m_started = true;
225 }
226 // ----------------------------------------------------------------------------
228  for_each( m_catalogs, []( IFileCatalog* i ) { i->commit(); } );
229 }
230 // ----------------------------------------------------------------------------
232  for_each( m_catalogs, []( IFileCatalog* i ) { i->rollback(); } );
233 }
234 // ----------------------------------------------------------------------------
236  // not yet initialized
237  if ( !m_started ) {
238  m_oldNames = m_catalogNames;
239  return;
240  } // RETURN
241  // no real change - no action
242  if ( m_catalogNames == m_oldNames ) { return; }
243  m_oldNames = m_catalogNames;
244  // remove ALL catalogs
245  removeCatalog( "" );
246  // add new catalogs
247  for ( const auto& inew : m_catalogNames ) addCatalog( inew );
248  // start
249  init();
250  //
251  debug() << "New catalogs to be used: " << Gaudi::Utils::toString( m_catalogNames ) << endmsg;
252 }
Gaudi::IFileCatalog::rollback
virtual void rollback()=0
Save catalog to file.
std::for_each
T for_each(T... args)
Gaudi::MultiFileCatalog::commit
void commit() override
Save DOM catalog to file.
Definition: MultiFileCatalog.cpp:227
Service::initialize
StatusCode initialize() override
Definition: Service.cpp:118
Gaudi::IFileCatalog::connectInfo
virtual const std::string & connectInfo() const =0
Access to connect string.
std::string
STL class.
std::exception
STL class.
Gaudi::IFileCatalog::readOnly
virtual bool readOnly() const =0
Check if the catalog is read-only.
cpluginsvc.registry
def registry()
Definition: cpluginsvc.py:83
Gaudi::MultiFileCatalog
Definition: MultiFileCatalog.h:30
Gaudi::IFileCatalog
Definition: IFileCatalog.h:36
Gaudi::IFileCatalog::commit
virtual void commit()=0
Save catalog to file.
gaudirun.s
string s
Definition: gaudirun.py:346
Gaudi::MultiFileCatalog::i_findCatalog
Catalogs::iterator i_findCatalog(CSTR connect, bool must_be_writable)
Find catalog by connect string.
Definition: MultiFileCatalog.cpp:85
std::find_if
T find_if(T... args)
strcasecmp.h
Gaudi::MultiFileCatalog::removeCatalog
void removeCatalog(CSTR connect) override
Remove catalog identified by name from the existing ones.
Definition: MultiFileCatalog.cpp:143
Gaudi::IFileCatalog::dirty
virtual bool dirty() const =0
Check if the catalog should be updated.
GaudiPartProp.decorators.get
get
decorate the vector of properties
Definition: decorators.py:283
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:19
gaudirun.c
c
Definition: gaudirun.py:525
std::all_of
T all_of(T... args)
Gaudi::MultiFileCatalog::findCatalog
IFileCatalog * findCatalog(CSTR connect, bool must_be_writable) const override
Catalog management
Definition: MultiFileCatalog.cpp:79
Service::finalize
StatusCode finalize() override
Definition: Service.cpp:222
AvalancheSchedulerErrorTest.msgSvc
msgSvc
Definition: AvalancheSchedulerErrorTest.py:80
PluginService.h
Gaudi::MultiFileCatalog::printError
void printError(CSTR msg, bool throw_exc=true) const
Definition: MultiFileCatalog.cpp:92
StatusCode
Definition: StatusCode.h:65
Gaudi::cxx::for_each
void for_each(ContainerOfSynced &c, Fun &&f)
Definition: SynchronizedValue.h:105
Gaudi::MultiFileCatalog::registerPFN
void registerPFN(CSTR fid, CSTR pfn, CSTR ftype) const override
Create a FileID and DOM Node of the PFN with all the attributes.
Definition: MultiFileCatalog.cpp:200
std::string::c_str
T c_str(T... args)
Gaudi::MultiFileCatalog::readOnly
bool readOnly() const override
Check if the catalog is read-only.
Definition: MultiFileCatalog.cpp:212
Gaudi::MultiFileCatalog::setWriteCatalog
void setWriteCatalog(IFileCatalog *cat) override
Define the writable catalog identified by reference.
Definition: MultiFileCatalog.cpp:165
std::runtime_error
STL class.
SmartIF
Definition: IConverter.h:25
Gaudi::MultiFileCatalog::finalize
StatusCode finalize() override
Finalize service object.
Definition: MultiFileCatalog.cpp:50
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
Gaudi::MultiFileCatalog::init
void init() override
Parse the DOM tree of the XML catalog.
Definition: MultiFileCatalog.cpp:222
Gaudi
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition: __init__.py:1
std::string::substr
T substr(T... args)
Gaudi::MultiFileCatalog::getMetaDataItem
std::string getMetaDataItem(CSTR fid, CSTR name) const override
Access metadata item.
Definition: MultiFileCatalog.cpp:191
Gaudi::Utils::toString
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition: ToStream.h:353
MultiFileCatalog.h
createGuidAsString.h
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
std::begin
T begin(T... args)
std
STL namespace.
DECLARE_COMPONENT
#define DECLARE_COMPONENT(type)
Definition: PluginServiceV1.h:46
IInterface
Definition: IInterface.h:239
Gaudi::IFileCatalog::init
virtual void init()=0
Parse the DOM tree of the XML catalog.
Gaudi::createGuidAsString
std::string createGuidAsString()
Helper function creating file identifier using the UUID mechanism.
Gaudi::MultiFileCatalog::connectInfo
CSTR connectInfo() const override
Access to connect string.
Definition: MultiFileCatalog.cpp:61
std::string::empty
T empty(T... args)
Gaudi::MultiFileCatalog::dirty
bool dirty() const override
Check if the catalog should be updated.
Definition: MultiFileCatalog.cpp:217
std::end
T end(T... args)
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
IInterface::release
virtual unsigned long release()=0
Release Interface instance.
Gaudi::MultiFileCatalog::registerLFN
void registerLFN(CSTR fid, CSTR lfn) const override
Create a FileID and DOM Node of the LFN with all the attributes.
Definition: MultiFileCatalog.cpp:206
Gaudi::MultiFileCatalog::rollback
void rollback() override
Save DOM catalog to file.
Definition: MultiFileCatalog.cpp:231
Gaudi::MultiFileCatalog::getCatalog
IFileCatalog * getCatalog(CSTR fid, bool throw_if_not, bool writable=true, bool prt=true) const
Find catalog containing a given file identifier.
Definition: MultiFileCatalog.cpp:66
IInterface::addRef
virtual unsigned long addRef()=0
Increment the reference count of Interface instance.
Gaudi::MultiFileCatalog::addCatalog
void addCatalog(CSTR connect) override
Add new catalog identified by name to the existing ones.
Definition: MultiFileCatalog.cpp:100
Gaudi::MultiFileCatalog::propHandler
void propHandler()
simple property handle to allow interactive modification of list of the file catalogs
Definition: MultiFileCatalog.cpp:235
MsgStream.h
Gaudi::MultiFileCatalog::createFID
std::string createFID() const override
Catalog interface
Definition: MultiFileCatalog.cpp:59