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"
14 using namespace Gaudi;
20 static std::set<std::string> s_badFiles;
30 "if set to True, we will not report when a file "
31 "is opened by it's physical name");
44 m_catalog = serviceLocator()->service(m_catalogSvcName);
45 if( !m_catalog.isValid() ) {
47 <<
"Unable to localize interface IFileCatalog from service:"
48 << m_catalogSvcName <<
endmsg;
51 m_incSvc = serviceLocator()->service(
"IncidentSvc");
52 if( !m_incSvc.isValid() ) {
77 IODataManager::Connections IODataManager::connections(
const IInterface* owner)
const {
79 for(ConnectionMap::const_iterator
i=m_connectionMap.begin();
i!=m_connectionMap.end();++
i) {
81 if ( 0 == owner || c->
owner() == owner )
88 StatusCode IODataManager::connectRead(
bool keep_open, Connection* con) {
89 if ( !establishConnection(con) ) {
92 std::string dsn = con ? con->name() : std::string(
"Unknown");
93 return error(
"Failed to connect to data:"+dsn,
false);
97 StatusCode IODataManager::connectWrite(Connection* con,IoType mode,
CSTR doctype) {
98 if ( !establishConnection(con) ) {
99 return connectDataIO(
UNKNOWN,mode,con->name(),doctype,
true,con);
101 std::string dsn = con ? con->name() : std::string(
"Unknown");
102 return error(
"Failed to connect to data:"+dsn,
false);
106 StatusCode IODataManager::read(Connection* con,
void*
const data,
size_t len) {
107 return establishConnection(con).
isSuccess() ? con->read(data,len) :
S_ERROR;
111 StatusCode IODataManager::write(Connection* con,
const void* data,
int len) {
112 return establishConnection(con).
isSuccess() ? con->write(data,len) :
S_ERROR;
116 long long int IODataManager::seek(Connection* con,
long long int where,
int origin) {
117 return establishConnection(con).isSuccess() ? con->seek(where,origin) : -1;
122 std::string dataset = con->name();
123 std::string dsn = dataset;
125 if ( ::strncasecmp(dsn.c_str(),
"FID:",4)==0 )
126 dsn = dataset.substr(4);
127 else if ( ::strncasecmp(dsn.c_str(),
"LFN:",4)==0 )
128 dsn = dataset.substr(4);
129 else if ( ::strncasecmp(dsn.c_str(),
"PFN:",4)==0 )
130 dsn = dataset.substr(4);
132 FidMap::iterator j = m_fidMap.find(dataset);
133 if ( j != m_fidMap.end() ) {
134 std::string fid = (*j).second;
135 std::string gfal_name =
"gfal:guid:" + fid;
136 ConnectionMap::iterator
i=m_connectionMap.find(fid);
138 if ( (j=m_fidMap.find(fid)) != m_fidMap.end() )
140 if ( (j=m_fidMap.find(gfal_name)) != m_fidMap.end() )
142 if ( i != m_connectionMap.end() ) {
145 std::string pfn = c->
pfn();
146 if ( (j=m_fidMap.find(pfn)) != m_fidMap.end() )
151 log <<
MSG::INFO <<
"Disconnect from dataset " << dsn
152 <<
" [" << fid <<
"]" <<
endmsg;
155 m_connectionMap.erase(i);
171 case Connection::UPDATE:
173 case Connection::RECREATE:
180 std::vector<Entry*> to_retire;
182 for(ConnectionMap::iterator
i=m_connectionMap.begin();
i!=m_connectionMap.end();++
i) {
186 if ( c->
age() > m_ageLimit ) {
187 to_retire.push_back((*i).second);
191 if ( !to_retire.empty() ) {
193 for(std::vector<Entry*>::iterator j=to_retire.begin(); j!=to_retire.end();++j) {
196 log <<
MSG::INFO <<
"Disconnect from dataset " << c->
pfn()
207 FidMap::const_iterator j = m_fidMap.find(dataset);
208 if ( j != m_fidMap.end() ) {
209 ConnectionMap::const_iterator
i=m_connectionMap.find((*j).second);
210 return (i != m_connectionMap.end()) ? (*i).second->connection : 0;
215 StatusCode IODataManager::establishConnection(Connection* con) {
217 if ( !con->isConnected() ) {
218 ConnectionMap::const_iterator
i=m_connectionMap.find(con->name());
219 if ( i != m_connectionMap.end() ) {
220 Connection*
c = (*i).second->connection;
223 return error(
"Severe logic bug: Twice identical connection object for DSN:"+con->name(),
true);
225 if ( reconnect((*i).second).isSuccess() ) {
234 return error(
"Severe logic bug: No connection object avalible.",
true);
238 IODataManager::connectDataIO(
int typ, IoType rw,
CSTR dataset,
CSTR technology,
bool keep_open,Connection* connection) {
240 std::string dsn = dataset;
243 if ( ::strncasecmp(dsn.c_str(),
"FID:",4)==0 )
244 dsn = dataset.substr(4), typ = FID;
245 else if ( ::strncasecmp(dsn.c_str(),
"LFN:",4)==0 )
246 dsn = dataset.substr(4), typ = LFN;
247 else if ( ::strncasecmp(dsn.c_str(),
"PFN:",4)==0 )
248 dsn = dataset.substr(4), typ = PFN;
250 return connectDataIO(PFN, rw, dsn, technology, keep_open, connection);
252 if(std::find(s_badFiles.begin(),s_badFiles.end(),dsn) != s_badFiles.end()) {
254 return IDataConnection::BAD_DATA_CONNECTION;
257 ConnectionMap::iterator fi = m_connectionMap.find(dsn);
258 if ( fi == m_connectionMap.end() ) {
260 m_catalog->getPFN(dsn,files);
261 if ( files.size() == 0 ) {
263 if ( m_quarantine ) s_badFiles.insert(dsn);
265 error(
"connectDataIO> failed to resolve FID:"+dsn,
false).ignore();
266 return IDataConnection::BAD_DATA_CONNECTION;
268 else if ( dsn.length() == 36 && dsn[8]==
'-' && dsn[13]==
'-' ) {
269 std::string gfal_name =
"gfal:guid:" + dsn;
270 m_fidMap[dsn] = m_fidMap[dataset] = m_fidMap[gfal_name] = dsn;
271 sc = connectDataIO(PFN, rw, gfal_name, technology, keep_open, connection);
273 if ( m_quarantine ) s_badFiles.insert(dsn);
275 if ( m_quarantine ) s_badFiles.insert(dsn);
277 error(
"connectDataIO> Failed to resolve FID:"+dsn,
false).ignore();
278 return IDataConnection::BAD_DATA_CONNECTION;
284 for(IFileCatalog::Files::const_iterator
i=files.begin();
i!=files.end(); ++
i) {
285 std::string pfn = (*i).first;
286 if (
i != files.begin() ) {
288 <<
" with next entry in data federation:" << pfn <<
"." <<
endmsg;
290 sc = connectDataIO(PFN, rw, pfn, technology, keep_open, connection);
292 if ( m_quarantine ) s_badFiles.insert(pfn);
296 m_fidMap[dsn] = m_fidMap[dataset] = m_fidMap[pfn] = dsn;
302 log <<
MSG::ERROR <<
"Failed to open dsn:" << dsn
303 <<
" Federated file could not be resolved from "
304 << files.size() <<
" entries." <<
endmsg;
305 return IDataConnection::BAD_DATA_CONNECTION;
310 FidMap::iterator j = m_fidMap.find(dsn);
311 if ( j == m_fidMap.end() ) {
315 fid = m_catalog->lookupLFN(dsn);
318 log <<
MSG::ERROR <<
"Failed to resolve LFN:" << dsn
319 <<
" Cannot access this dataset." <<
endmsg;
320 return IDataConnection::BAD_DATA_CONNECTION;
324 fid = m_catalog->lookupPFN(dsn);
325 if ( !fid.empty() ) m_catalog->getPFN(fid, files);
326 if ( files.empty() ) {
328 if ( fid.empty() ) fid = m_catalog->createFID();
329 m_catalog->registerPFN(fid,dsn,technology);
330 log <<
MSG::INFO <<
"Referring to dataset " << dsn
331 <<
" by its file ID:" << fid <<
endmsg;
345 ConnectionMap::iterator fi = m_connectionMap.find(fid);
346 if ( fi == m_connectionMap.end() ) {
347 connection->setFID(fid);
348 connection->setPFN(dsn);
349 Entry* e =
new Entry(technology, keep_open, rw, connection);
351 if ( !reconnect(e).isSuccess() ) {
353 if ( m_quarantine ) s_badFiles.insert(dsn);
355 error(
"connectDataIO> Cannot connect to database: PFN="+dsn+
" FID="+fid,
false).ignore();
356 return IDataConnection::BAD_DATA_CONNECTION;
358 fid = connection->fid();
359 m_fidMap[dataset] = m_fidMap[dsn] = m_fidMap[fid] = fid;
361 if ( ! m_disablePFNWarning && strcasecmp(dsn.c_str(),fid.c_str()) == 0 ) {
362 log <<
MSG::ERROR <<
"Referring to existing dataset " << dsn
363 <<
" by its physical name." <<
endmsg;
364 log <<
"You may not be able to navigate back to the input file"
365 <<
" -- processing continues" <<
endmsg;
368 m_connectionMap.insert(std::make_pair(fid,e));
372 if ( !reconnect((*fi).second).isSuccess() ) {
373 if ( m_quarantine ) s_badFiles.insert(dsn);
375 error(
"connectDataIO> Cannot connect to database: PFN="+dsn+
" FID="+fid,
false).ignore();
376 return IDataConnection::BAD_DATA_CONNECTION;
380 sc = connectDataIO(FID, rw, fid, technology, keep_open, connection);
382 s_badFiles.insert(fid);
384 else if ( typ == LFN ) {
385 m_fidMap[dataset] = fid;
389 catch (std::exception& e) {
390 error(std::string(
"connectDataIO> Caught exception:")+e.what(),
false).ignore();
393 error(std::string(
"connectDataIO> Caught unknown exception"),
false).ignore();
396 error(
"connectDataIO> The dataset "+dsn+
" cannot be opened.",
false).ignore();
397 s_badFiles.insert(dsn);
398 return IDataConnection::BAD_DATA_CONNECTION;