2 #include "GaudiKernel/Debugger.h"
3 #include "GaudiKernel/MsgStream.h"
4 #include "GaudiKernel/strcasecmp.h"
5 #include "GaudiUtils/IFileCatalog.h"
7 #include "GaudiKernel/SmartIF.h"
8 #include "GaudiKernel/Incident.h"
9 #include "GaudiKernel/IIncidentSvc.h"
10 #include "GaudiKernel/AppReturnCode.h"
16 constexpr
struct select2nd_t {
17 template<
typename S,
typename T>
18 const T& operator()(
const std::pair<S,T>& p)
const {
return p.second; }
21 template <
typename InputIterator,
typename OutputIterator,
22 typename UnaryOperation,
typename UnaryPredicate>
23 OutputIterator transform_copy_if( InputIterator first, InputIterator last,
24 OutputIterator result,
26 UnaryPredicate pred) {
27 while (first != last) {
28 auto val = op(*first);
29 if (pred(val)) *result++ = std::move(val);
36 using namespace Gaudi;
42 static std::set<std::string> s_badFiles;
47 declareProperty(
"CatalogType",
m_catalogSvcName=
"Gaudi::MultiFileCatalog/FileCatalog");
48 declareProperty(
"UseGFAL",
m_useGFAL =
true);
52 "if set to True, we will not report when a file "
53 "is opened by its physical name");
69 <<
"Unable to localize interface IFileCatalog from service:"
73 m_incSvc = serviceLocator()->service(
"IncidentSvc");
99 std::back_inserter(conns),
100 [](ConnectionMap::const_reference
i ) {
return i.second->connection; },
110 std::string dsn = con ? con->name() : std::string(
"Unknown");
111 return error(
"Failed to connect to data:"+dsn,
false);
119 std::string dsn = con ? con->name() : std::string(
"Unknown");
120 return error(
"Failed to connect to data:"+dsn,
false);
140 std::string dataset = con->name();
141 std::string dsn = dataset;
143 if ( ::strncasecmp(dsn.c_str(),
"FID:",4)==0 )
144 dsn = dataset.substr(4);
145 else if ( ::strncasecmp(dsn.c_str(),
"LFN:",4)==0 )
146 dsn = dataset.substr(4);
147 else if ( ::strncasecmp(dsn.c_str(),
"PFN:",4)==0 )
148 dsn = dataset.substr(4);
152 std::string fid = j->second;
153 std::string gfal_name =
"gfal:guid:" + fid;
167 log <<
MSG::INFO <<
"Disconnect from dataset " << dsn
168 <<
" [" << fid <<
"]" <<
endmsg;
186 case Connection::UPDATE:
188 case Connection::RECREATE:
195 std::vector<Entry*> to_retire;
198 std::back_inserter(to_retire),
205 if ( !to_retire.empty() ) {
211 log <<
MSG::INFO <<
"Disconnect from dataset " << c->
pfn()
223 if ( j ==
m_fidMap.end() )
return nullptr;
229 if ( !con )
return error(
"Severe logic bug: No connection object avalible.",
true);
231 if ( con->isConnected() ) {
237 Connection*
c =
i->second->connection;
240 return error(
"Severe logic bug: Twice identical connection object for DSN:"+con->name(),
true);
250 std::string dsn = dataset;
253 if ( ::strncasecmp(dsn.c_str(),
"FID:",4)==0 )
254 dsn = dataset.substr(4), typ = FID;
255 else if ( ::strncasecmp(dsn.c_str(),
"LFN:",4)==0 )
256 dsn = dataset.substr(4), typ = LFN;
257 else if ( ::strncasecmp(dsn.c_str(),
"PFN:",4)==0 )
258 dsn = dataset.substr(4), typ = PFN;
260 return connectDataIO(PFN, rw, dsn, technology, keep_open, connection);
262 if(std::find(s_badFiles.begin(),s_badFiles.end(),dsn) != s_badFiles.end()) {
271 if ( files.empty() ) {
275 error(
"connectDataIO> failed to resolve FID:"+dsn,
false).
ignore();
278 else if ( dsn.length() == 36 && dsn[8]==
'-' && dsn[13]==
'-' ) {
279 std::string gfal_name =
"gfal:guid:" + dsn;
281 sc =
connectDataIO(PFN, rw, gfal_name, technology, keep_open, connection);
287 error(
"connectDataIO> Failed to resolve FID:"+dsn,
false).
ignore();
292 auto appmgr = serviceLocator()->as<
IProperty>();
294 for(
auto i=files.cbegin();
i!=files.cend(); ++
i) {
295 std::string pfn =
i->first;
296 if (
i != files.cbegin() ) {
298 <<
" with next entry in data federation:" << pfn <<
"." <<
endmsg;
300 sc =
connectDataIO(PFN, rw, pfn, technology, keep_open, connection);
312 log <<
MSG::ERROR <<
"Failed to open dsn:" << dsn
313 <<
" Federated file could not be resolved from "
314 << files.size() <<
" entries." <<
endmsg;
328 log <<
MSG::ERROR <<
"Failed to resolve LFN:" << dsn
329 <<
" Cannot access this dataset." <<
endmsg;
335 if ( !fid.empty() )
m_catalog->getPFN(fid, files);
336 if ( files.empty() ) {
338 if ( fid.empty() ) fid =
m_catalog->createFID();
339 m_catalog->registerPFN(fid,dsn,technology);
340 log <<
MSG::INFO <<
"Referring to dataset " << dsn
341 <<
" by its file ID:" << fid <<
endmsg;
357 connection->setFID(fid);
358 connection->setPFN(dsn);
359 auto e =
new Entry(technology, keep_open, rw, connection);
365 error(
"connectDataIO> Cannot connect to database: PFN="+dsn+
" FID="+fid,
false).
ignore();
368 fid = connection->fid();
372 log <<
MSG::ERROR <<
"Referring to existing dataset " << dsn
373 <<
" by its physical name." <<
endmsg;
374 log <<
"You may not be able to navigate back to the input file"
375 <<
" -- processing continues" <<
endmsg;
385 error(
"connectDataIO> Cannot connect to database: PFN="+dsn+
" FID="+fid,
false).
ignore();
390 sc =
connectDataIO(FID, rw, fid, technology, keep_open, connection);
392 s_badFiles.insert(fid);
394 else if ( typ == LFN ) {
399 catch (std::exception& e) {
400 error(std::string(
"connectDataIO> Caught exception:")+e.what(),
false).ignore();
403 error(std::string(
"connectDataIO> Caught unknown exception"),
false).
ignore();
406 error(
"connectDataIO> The dataset "+dsn+
" cannot be opened.",
false).
ignore();
407 s_badFiles.insert(dsn);
StatusCode finalize() override
IService implementation: finalize the service.
int getAppReturnCode(const SmartIF< IProperty > &appmgr)
Get the application (current) return code.
Definition of the MsgStream class used to transmit messages.
StatusCode initialize() override
virtual StatusCode connectWrite(IoType type)=0
Open data stream in write mode.
virtual StatusCode disconnect()=0
Release data stream.
int m_ageLimit
Property: Age limit.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
virtual bool isConnected() const =0
Check if connected to data source.
bool m_useGFAL
Property: Flag for auto gfal data access.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
const std::string & fid() const
Access file id.
StatusCode finalize() override
bool isSuccess() const
Test for a status code of SUCCESS.
auto begin(reverse_wrapper< T > &w)
std::vector< NamedItem > Files
StatusCode disconnect(Connection *ioDesc) override
Release data stream.
SmartIF< IIncidentSvc > m_incSvc
StatusCode establishConnection(Connection *con)
std::string m_catalogSvcName
Property: Name of the file catalog service.
StatusCode error(CSTR msg, bool rethrow)
Small routine to issue exceptions.
const std::string & pfn() const
Access physical file name.
bool m_disablePFNWarning
Property DisablePFNWarning: if set to True will not report when a file is opened by it's physical nam...
StatusCode read(Connection *ioDesc, void *const data, size_t len) override
Read raw byte buffer from input stream.
Connection * connection(const std::string &dsn) const override
Retrieve known connection.
GAUDI_API long breakExecution()
Break the execution of the application and invoke the debugger.
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
int ageFile()
Increase age of I/O source.
StatusCode initialize() override
IService implementation: initialize the service.
auto end(reverse_wrapper< T > &w)
This class is used for returning status codes from appropriate routines.
SmartIF< IFileCatalog > m_catalog
Reference to file catalog.
#define DECLARE_COMPONENT(type)
Definition of the basic interface.
StatusCode write(Connection *con, const void *data, int len) override
Write raw byte buffer to output stream.
StatusCode connectWrite(Connection *con, IoType mode=Connection::CREATE, CSTR doctype="UNKNOWN") override
Open data stream in write mode.
StatusCode setAppReturnCode(SmartIF< IProperty > &appmgr, int value, bool force=false)
Set the application return code.
bool m_quarantine
Property: Flag if unaccessible files should be quarantines in job.
ABC describing basic data connection.
Base class used to extend a class implementing other interfaces.
ConnectionMap m_connectionMap
Map with I/O descriptors.
IDataConnection * connection
void resetAge()
Reset age.
Base class for all Incidents (computing events).
StatusCode connectDataIO(int typ, IoType rw, CSTR fn, CSTR technology, bool keep, Connection *con)
StatusCode connectRead(bool keep_open, Connection *ioDesc) override
Open data stream in read mode.
The IProperty is the basic interface for all components which have properties that can be set or get...
virtual StatusCode connectRead()=0
Open data stream in read mode.
Connections connections(const IInterface *owner) const override
Get connection by owner instance (0=ALL)
long long int seek(Connection *ioDesc, long long int where, int origin) override
Seek on the file described by ioDesc. Arguments as in ::seek()
Helper functions to set/get the application return code.
StatusCode reconnect(Entry *e)
IODataManager(CSTR nam, ISvcLocator *loc)
the incident service
FidMap m_fidMap
Map of FID to PFN.