ATLAS Offline Software
Loading...
Searching...
No Matches
IOVRegistrationSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
14
15//<<<<<< INCLUDES >>>>>>
16
17#include "IOVRegistrationSvc.h"
18
19// Athena includes
22
23// Gaudi includes
24#include "GaudiKernel/IAddressCreator.h"
25#include "GaudiKernel/IClassIDSvc.h"
26#include "GaudiKernel/IConversionSvc.h"
27#include "GaudiKernel/IOpaqueAddress.h"
28#include "GaudiKernel/IConverter.h"
29
30// AttrList and address
35
36// COOL includes
37//#include "AttributeList/AttributeList.h"
38#include "CoolKernel/IDatabase.h"
39#include "CoolKernel/IFolder.h"
40#include "CoolKernel/RecordSpecification.h"
41#include "CoolKernel/FolderSpecification.h"
42#include "CoolKernel/Record.h"
43
44//<<<<<< METHOD DEFINITIONS
45
46//--------------------------------------------------------------------------
47
48IOVRegistrationSvc::IOVRegistrationSvc( const std::string& name, ISvcLocator* svc )
49 :
50 base_class( name, svc ),
51 m_iov_db ( "IOVDbSvc", name ),
52 m_detStore( "DetectorStore", name ),
53 m_persSvc ( "EventPersistencySvc", name ),
54 m_clidSvc ( "ClassIDSvc", name )
55{
56
57}
58
59//--------------------------------------------------------------------------
62
63const InterfaceID& IOVRegistrationSvc::type() const
64
65{
66 return IIOVRegistrationSvc::interfaceID();
67}
68
69//--------------------------------------------------------------------------
70
72{
73 ATH_MSG_DEBUG ("in initialize()");
74
75 StatusCode sc = AthService::initialize();
76 if ( sc.isFailure() ) {
77 ATH_MSG_ERROR ("Unable to call base initialize method");
78 return StatusCode::FAILURE;
79 }
80
81 // locate the conditions store ptr to it.
82 sc = m_detStore.retrieve();
83 if (!sc.isSuccess() || 0 == m_detStore) {
84 ATH_MSG_ERROR ("Could not find ConditionStore");
85 return StatusCode::FAILURE;
86 }
87
88 // Get the IOVDbSvc
89 sc = m_iov_db.retrieve();
90 if ( sc.isFailure() ) {
91 ATH_MSG_ERROR ("Unable to get the IOVDbSvc");
92 return StatusCode::FAILURE;
93 }
94
95 // Get the persistency mgr for conversion of IOpaqueAddress to
96 // string
97 sc = m_persSvc.retrieve();
98 if ( sc != StatusCode::SUCCESS ) {
99 ATH_MSG_ERROR (" Cannot get IAddressCreator interface of the EventPersistencySvc ");
100 return sc ;
101 }
102 ATH_MSG_DEBUG ("Found PersistencySvc ");
103
104
105 // Get the ClassIDSvc - to get typename for clid
106 sc = m_clidSvc.retrieve();
107 if (sc != StatusCode::SUCCESS ) {
108 ATH_MSG_ERROR (" Cannot get IClassIDSvc interface of the CLIDSvc " );
109 return sc ;
110 }
111 ATH_MSG_DEBUG ("Found CLIDSvc ");
112
113
114 ATH_MSG_DEBUG ("Properties ");
115 ATH_MSG_DEBUG ("RecreateFolders " << m_recreateFolders);
116 if (m_timeStamp)
117 {
118 ATH_MSG_DEBUG ("BeginTime " << m_beginTime);
119 ATH_MSG_DEBUG ("EndTime " << m_endTime);
120 }
121 else
122 {
123 ATH_MSG_DEBUG ("BeginRun " << m_beginRun);
124 ATH_MSG_DEBUG ("EndRun " << m_endRun);
125 ATH_MSG_DEBUG ("BeginLB " << m_beginLB);
126 ATH_MSG_DEBUG ("EndLB " << m_endLB);
127 }
128 ATH_MSG_DEBUG ("IOVDbTag " << m_tag);
129
130 // check consistency of override specification, if any
131 if (m_overrideName.size()!=m_overrideType.size()) {
132 ATH_MSG_FATAL ("Inconsistent settings of OverrideNames and OverrideTypes parameters");
133 return StatusCode::FAILURE;
134 }
135 for (unsigned int i=0;i<m_overrideName.size();++i)
136 ATH_MSG_INFO ("Attributes with name " << m_overrideName[i] <<
137 " will be stored as COOL type " << m_overrideType[i]);
138 return StatusCode::SUCCESS;
139
140}
141
142//--------------------------------------------------------------------------
143
145{
146 return StatusCode::SUCCESS;
147}
148
149//--------------------------------------------------------------------------
150
151StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName ) const
152{
153 std::string key = "";
154
155 if (m_timeStamp)
156 {
157 IOVTime start;
158 start.setTimestamp(timeToNano(m_beginTime));
159 IOVTime stop ;
160 stop.setTimestamp(timeToNano(m_endTime));
161
162 return ( registerIOV( typeName,
163 key,key,
164 m_tag.value(),
165 start,
166 stop) );
167 }
168 else
169 {
170 IOVTime start;
171 start.setRunEvent( (unsigned long)m_beginRun, (unsigned long)m_beginLB );
172 IOVTime stop;
173 stop.setRunEvent ( (unsigned long)m_endRun, (unsigned long)m_endLB );
174
175 return ( registerIOV( typeName,
176 key,key,
177 m_tag.value(),
178 start,
179 stop) );
180 }
181}
182
183//--------------------------------------------------------------------------
184
185StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName, const std::string& tag ) const
186{
187 std::string key = "";
188
189 if (m_timeStamp)
190 {
191 IOVTime start;
192 start.setTimestamp( timeToNano(m_beginTime) );
193 IOVTime stop ;
194 stop.setTimestamp ( timeToNano(m_endTime) );
195
196 return ( registerIOV( typeName,
197 key,key,
198 tag,
199 start,
200 stop) );
201 }
202 else
203 {
204 IOVTime start;
205 start.setRunEvent( (unsigned long)m_beginRun, (unsigned long)m_beginLB );
206 IOVTime stop;
207 stop.setRunEvent ( (unsigned long)m_endRun, (unsigned long)m_endLB );
208
209 return ( registerIOV( typeName,
210 key,key,
211 tag,
212 start,
213 stop) );
214 }
215}
216
217//--------------------------------------------------------------------------
218
219StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName, const std::string& key,
220 const std::string& tag ) const
221{
222 if (m_timeStamp)
223 {
224 IOVTime start;
225 start.setTimestamp( timeToNano(m_beginTime) );
226 IOVTime stop ;
227 stop.setTimestamp ( timeToNano(m_endTime) );
228
229 return ( registerIOV( typeName,
230 key,key,
231 tag,
232 start,
233 stop) );
234 }
235 else
236 {
237 IOVTime start;
238 start.setRunEvent( (unsigned long)m_beginRun, (unsigned long)m_beginLB );
239 IOVTime stop;
240 stop.setRunEvent ( (unsigned long)m_endRun, (unsigned long)m_endLB );
241
242 return ( registerIOV( typeName,
243 key,key,
244 tag,
245 start,
246 stop) );
247 }
248}
249
250//--------------------------------------------------------------------------
251
252StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName,
253 const std::string& tag,
254 unsigned int beginRun,
255 unsigned int endRun,
256 unsigned int beginLB,
257 unsigned int endLB ) const
258{
259 IOVTime start;
260 start.setRunEvent( (unsigned long)beginRun, (unsigned long)beginLB );
261 IOVTime stop;
262 stop.setRunEvent ( (unsigned long)endRun, (unsigned long)endLB );
263 std::string key = "";
264
265 return ( registerIOV( typeName,
266 key,key,
267 tag,
268 start,
269 stop) );
270}
271
272//--------------------------------------------------------------------------
273
274StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName,
275 const std::string& tag,
276 uint64_t beginTime,
277 uint64_t endTime ) const
278{
279 IOVTime start;
280 start.setTimestamp( beginTime );
281 IOVTime stop;
282 stop.setTimestamp ( endTime );
283
284 std::string key = "";
285
286 return ( registerIOV( typeName,
287 key,key,
288 tag,
289 start,
290 stop) );
291}
292
293//--------------------------------------------------------------------------
294
295StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName,
296 const std::string& key,
297 const std::string& tag,
298 unsigned int beginRun,
299 unsigned int endRun,
300 unsigned int beginLB,
301 unsigned int endLB ) const
302{
303 IOVTime start;
304 start.setRunEvent( (unsigned long)beginRun, (unsigned long)beginLB );
305 IOVTime stop;
306 stop.setRunEvent ( (unsigned long)endRun, (unsigned long)endLB );
307
308 return ( registerIOV( typeName,
309 key,key,
310 tag,
311 start,
312 stop) );
313}
314
315//--------------------------------------------------------------------------
316
317StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName,
318 const std::string& key,
319 const std::string& tag,
320 uint64_t beginTime,
321 uint64_t endTime ) const
322{
323 IOVTime start;
324 start.setTimestamp( beginTime );
325 IOVTime stop;
326 stop.setTimestamp ( endTime );
327
328 return ( registerIOV( typeName,
329 key,key,
330 tag,
331 start,
332 stop) );
333}
334
335//--------------------------------------------------------------------------
336
337StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName,
338 const std::string& key,
339 const std::string& folder,
340 const std::string& tag,
341 unsigned int beginRun,
342 unsigned int endRun,
343 unsigned int beginLB,
344 unsigned int endLB ) const
345{
346 IOVTime start;
347 start.setRunEvent( (unsigned long)beginRun, (unsigned long)beginLB );
348 IOVTime stop;
349 stop.setRunEvent ( (unsigned long)endRun, (unsigned long)endLB );
350
351 return ( registerIOV( typeName,
352 key,
353 folder,
354 tag,
355 start,
356 stop) );
357}
358
359//--------------------------------------------------------------------------
360
361StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName,
362 const std::string& key,
363 const std::string& folder,
364 const std::string& tag,
365 uint64_t beginTime,
366 uint64_t endTime ) const
367{
368 IOVTime start;
369 start.setTimestamp( beginTime );
370 IOVTime stop;
371 stop.setTimestamp ( endTime );
372
373 return ( registerIOV( typeName,
374 key,
375 folder,
376 tag,
377 start,
378 stop) );
379}
380
382// Private methods
384
385//--------------------------------------------------------------------------
386
387StatusCode IOVRegistrationSvc::registerIOV( const std::string& typeName,
388 const std::string& spec_key,
389 const std::string& folder,
390 const std::string& tag,
391 const IOVTime& start,
392 const IOVTime& stop ) const
393{
394 // Register the conditions objects in the IOV database with
395 // start/stop as the time interval
396
397
398 msg() << MSG::DEBUG <<" in registerIOV()"
399 << " typename: " << typeName << " - tag: " << tag;
400 if (spec_key.empty())
401 {
402 msg() << " key: *empty* " << endmsg;
403 }
404 else
405 {
406 msg() << " spec_key " << spec_key << endmsg;
407 }
408 msg() << " - begin time: " << start
409 << " - end time: " << stop
410 << endmsg;
411
412 // Check validity of start/stop
413 if(start.isBoth() || stop.isBoth() ||
414 start.isTimestamp() != stop.isTimestamp() ||
415 start.isRunEvent() != stop.isRunEvent()) {
416 ATH_MSG_ERROR ("Incorrect start/stop: "
417 << " isBoth: " << start.isBoth() << ":" << stop.isBoth()
418 << " isTimestamp: " << start.isTimestamp() << ":" << stop.isTimestamp()
419 << " isRunEvent: " << start.isRunEvent() << ":" << stop.isRunEvent());
420 return( StatusCode::FAILURE);
421 }
422
423 return registerIOVCOOL( typeName,
424 spec_key,
425 folder,
426 tag,
427 start,
428 stop );
429}
430
431
432
433//--------------------------------------------------------------------------
434
435StatusCode IOVRegistrationSvc::registerIOVCOOL( const std::string& typeName,
436 const std::string& spec_key,
437 const std::string& folderName,
438 const std::string& tag,
439 const IOVTime& start,
440 const IOVTime& stop ) const
441{
442 // Register the conditions objects in the IOV database with
443 // start/stop as the time interval
444
445
446 ATH_MSG_DEBUG (" in registerIOVCOOL()" );
447
448
449 // Find the clid for type name from the CLIDSvc
450 CLID clid;
451 StatusCode sc = m_clidSvc->getIDOfTypeName(typeName, clid);
452 if (sc.isFailure()) {
453 ATH_MSG_ERROR ("Could not get clid for typeName " << typeName);
454 return( StatusCode::FAILURE);
455 }
456
457 try {
458
459 // There are two possible states:
460 // 1) The DataObject is stored elsewhere and we store in the
461 // IOVDb only a stringified ref to the object, or
462 // 2) The DataObject is an AthenaAttributeList or a
463 // CondAttrListCollection and then we store it directly into
464 // the IOVDb.
465 //
466 // The second case is detected either with the type name,
467 // for AthenaAttributeList or CondAttrListCollection, or by
468 // checking the real type of the IOA - i.e. if it is a
469 // CondAttrListCollAddress then a CondAttrListCollection may
470 // have been filled with pool refs stored in it.
471
472 bool storeRef = true;
473 bool storeAttrListColl = false;
474 bool needSGaddr=false;
475 if ("AthenaAttributeList" == typeName) {
476 storeRef = false;
477 needSGaddr=false;
478 }
479 if ("CondAttrListCollection" == typeName) {
480 storeRef = false;
481 storeAttrListColl = true;
482 needSGaddr=false;
483 }
484 // (See after retrieval of the IOA for a final check of the
485 // type of storage.)
486
487 // Get IOpaqueAddress, key and symlinks for each data object
488 // from StoreGate
489 IOpaqueAddress* addr=0;
490 std::string key = spec_key;
491 std::vector<CLID> symlinks;
492 SG::DataProxy* proxy;
493 if (key.empty()) {
494 // Get IOpaqueAddress and key for each data object from
495 // StoreGate
496 proxy = m_detStore->proxy(clid);
497 if (!proxy) {
498 ATH_MSG_ERROR ("Could not get proxy for clid " << clid);
499 return( StatusCode::FAILURE);
500 }
501
502 // Get key to be used for folder name
503 key = proxy->name();
504 // get proxy address - this will fail if object not streamed out
505 // but this can be recovered later for inline data
506 addr = proxy->address();
507 } else {
508 // Get IOpaqueAddress for each data object from StoreGate
509 proxy = m_detStore->proxy(clid, key);
510 if (!proxy) {
511 ATH_MSG_ERROR ("Could not get proxy for clid " << clid << " and key " << key);
512 return( StatusCode::FAILURE );
513 }
514 // get proxy address - this will fail if object not streamed out
515 // but this can be recovered later for inline data
516 addr = proxy->address();
517 }
518 std::string saddr;
519 if (addr) {
520 // Get symlinks, if any
521 symlinks = proxy->transientID();
522 auto it = std::find (symlinks.begin(), symlinks.end(), clid);
523 if (it != symlinks.end()) {
524 symlinks.erase (it);
525 }
526
527 // Check whether the IOA is a CondAttrListCollAddress - if so
528 // we will store a CondAttrListCollection
529 CondAttrListCollAddress* collAddr = dynamic_cast<CondAttrListCollAddress*>(addr);
530 if (collAddr) {
531 storeRef = false;
532 storeAttrListColl = true;
533 }
534 // Convert IOpaqueAddress to string via the persistency
535 // service. We then store the string address in the IOV DB
536 sc = m_persSvc->convertAddress(addr, saddr);
537 if (sc.isFailure()) {
538 ATH_MSG_WARNING ("Could not get string from IOpaqueAddress for clid " << clid
539 << " is BAD_STORAGE_TYPE: " << (sc == IConversionSvc::Status::BAD_STORAGE_TYPE));
540 return( StatusCode::FAILURE);
541 }
542 ATH_MSG_DEBUG ("String address = \"" << saddr << "\"");
543 } else {
544 // if no addr was found, object has not been streamed out
545 // this is OK providing we do not need the addr later
546 // i.e. plain CondAttrListCollection or AthenaAttributeList
547 if (needSGaddr) {
548 ATH_MSG_ERROR ("Could not get address for clid " << clid);
549 return( StatusCode::FAILURE );
550 } else {
551 ATH_MSG_DEBUG ("Faking address for " << typeName);
552 // fake the saddr contents
553 if ("AthenaAttributeList" == typeName) {
554 saddr="<address_header service_type=\"256\" clid=\"40774348\" /> POOLContainer_AthenaAttributeList][CLID=x";
555 } else if ("CondAttrListCollection" == typeName) {
556 saddr="<address_header service_type=\"256\" clid=\"1238547719\" /> POOLContainer_CondAttrListCollection][CLID=x";
557 } else {
558 ATH_MSG_ERROR ("Cannot fake stringaddress for typename "
559 << typeName);
560 }
561 }
562 }
563
564 ATH_MSG_DEBUG ("Storing ref: " << storeRef
565 << " Storing AttrListCollection: " << storeAttrListColl);
566
567 // Set folder name - in the present case this is defined
568 // to be the key
569 // RJH - unless a non-null folder is given on input
570 std::string local_folder;
571 if (""==folderName) {
572 local_folder = key;
573 } else {
574 local_folder=folderName;
575 }
576 ATH_MSG_DEBUG ("Using folder name " << local_folder);
577
578 // Get COOL database in update mode (false == readOnly flag)
579 cool::IDatabasePtr db = m_iov_db->getDatabase(false);
580 if (!db) {
581 ATH_MSG_ERROR ("Could not get pointer to COOL db ");
582 return(StatusCode::FAILURE);
583 }
584 // get some information about the database connection for later checks
585 const cool::DatabaseId& dbid=db->databaseId();
586 // look for direct connection to production accounts
587 bool dbidprod=(dbid.find("oracle")!=std::string::npos && (
588 dbid.find("ATLAS_COOLONL_")!=std::string::npos ||
589 dbid.find("ATLAS_COOLOFL_")!=std::string::npos ||
590 dbid.find("ATLAS_COOL_")!=std::string::npos));
591 // look for use of writer account ('_W' in connection string)
592 bool dbidwriter=(dbid.find("oracle")!=std::string::npos &&
593 dbid.find("_W")!=std::string::npos);
594 ATH_MSG_DEBUG ("Identified prod/writer " << dbidprod << dbidwriter);
595 // do not allow write accesss to production servers
596 if (dbidprod) {
597 ATH_MSG_FATAL ("Direct update of production Oracle servers from Athena is FORBIDDEN");
598 ATH_MSG_FATAL ("Please write to SQLite file and then merge with AtlCoolMerge.py");
599 return StatusCode::FAILURE;
600 }
601
602 // For AthenaAttributeList/CondAttrListCollection, save a pointer to the object
603 const AthenaAttributeList* attrList = 0;
604 const CondAttrListCollection* attrListColl = 0;
605
606 if (!storeRef) {
607 if ("CondAttrListCollection"==typeName) {
608 if (StatusCode::SUCCESS!=m_detStore->
609 retrieve(attrListColl,key)) {
610 ATH_MSG_ERROR ("Could not find CondAttrListCollecton for "
611 << key);
612 return StatusCode::FAILURE;
613 }
614 } else if (storeAttrListColl) {
615 // have to go through SG proxy, as it is a collection of POOLref
616 if (addr) {
617 CondAttrListCollAddress* attrAddr = dynamic_cast<CondAttrListCollAddress*>(addr);
618 if (attrAddr) {
619 // Successful cast
620 attrListColl = attrAddr->attrListColl();
621 ATH_MSG_DEBUG ("Set attr list coll ptr ");
622 ATH_MSG_DEBUG ("addr, attrAddr, coll "
623 << addr << " " << attrAddr << " " << attrListColl);
624 } else {
625 ATH_MSG_ERROR ("Could not extract ptr for CondAttrListCollAddress ");
626 return StatusCode::FAILURE;
627 }
628 } else {
629 ATH_MSG_ERROR ("Cannot write out collection of POOLref without streaming them first" );
630 return StatusCode::FAILURE;
631 }
632 } else {
633 // Just AttrList - get directly from Storegate
634 if (StatusCode::SUCCESS!=m_detStore->retrieve(attrList,key)) {
635 ATH_MSG_ERROR ("Could not find AthenaAttributeList for "
636 << key);
637 return StatusCode::FAILURE;
638 }
639 }
640
641 }
642
643
644 ATH_MSG_DEBUG ("Set attr list coll ptr " << attrListColl);
645
646 // Save folder pointer
647 cool::IFolderPtr folder;
648
649 // Create folders if required - a job option allows on to
650 // delete existing folders and then recreate them
651
652 bool createFolders = false;
653
654 if(db->existsFolder(local_folder)) {
655
656 if (m_recreateFolders) {
657 // do not allow this action on production schema or with writer
658 if (dbidprod || dbidwriter) {
659 ATH_MSG_FATAL ("Apparent attempt to delete folder on production COOL schema " << dbid);
660 return StatusCode::FAILURE;
661 }
662
663 ATH_MSG_DEBUG (" Deleting existing COOL Folder " << local_folder);
664 db->dropNode( local_folder );
665 createFolders = true;
666 }
667 else {
668 // Get folder
669 ATH_MSG_DEBUG ("COOL Folder " << local_folder << " exists");
670 folder = db->getFolder(local_folder);
671 }
672
673 }
674 else {
675 ATH_MSG_DEBUG ("COOL Folder " << local_folder
676 << " does not exist - must create it");
677 createFolders = true;
678 }
679
680 // Split the string address into header and data parts
681 std::string address_header;
682 std::string address_data;
683
684 sc = splitAddress(saddr,address_header,address_data);
685 if (sc.isFailure()) {
686 ATH_MSG_ERROR ("Could not split address: "
687 << "addr: " << saddr << "\n"
688 << "hdr: " << address_header << "\n"
689 << "data " << address_data);
690 return( StatusCode::FAILURE);
691 }
692 msg() << MSG::DEBUG <<"split address: " << saddr << endmsg
693 << " hdr: " << address_header << endmsg
694 << " data: " << address_data << endmsg;
695
696
697 if(createFolders) {
698 // first make sure not using writer account -if so abort
699 if (dbidwriter) {
700 ATH_MSG_FATAL ("Apparent attempt to create folder using writer account, dbID is: " << dbid);
701 return StatusCode::FAILURE;
702 }
703
704 // We store extra information in the folder description.
705 // This info is:
706 // typeName - required information
707 // symlinks - the extra StoreGate keys, if any
708 // key - optional, only needed if key != folder name
709 // timeStamp - either run-lumi (default) or time
710 // address_header - added by convention
711 //
712 //
713 // The convention is that the address_header is stored
714 // in the description, and the IOV interval data
715 // payload is just the pool reference in string form.
716 // The address_header and address_data can be obtained
717 // from the string address returned from the
718 // persistency service, using splitAddress
719
720 std::string mergedNames;
721
722 sc = buildDescription( "typeName", typeName,
723 mergedNames );
724 if (sc.isFailure()) {
725 ATH_MSG_ERROR ("Could not merge towards merged description: "
726 << "typeName: " << typeName);
727 return( StatusCode::FAILURE);
728 }
729
730 sc = buildDescription( "addrHeader", address_header,
731 mergedNames );
732 if (sc.isFailure()) {
733 ATH_MSG_ERROR ("Could not merge towards merged description: "
734 << "addrHeader: " << address_header);
735 return( StatusCode::FAILURE);
736 }
737 // RJH - if key is not same as folder, and we want the read-back
738 // objects to end up in the TDS with the given Storegate key rather
739 // than the folder name, need to set the <key> attribute
740 // a jobOption WriteKeyInfo=FALSE disables this, in case you have
741 // created objects with the 'wrong' SG key and want the key
742 // on read-back to correspond to the folder name
743 if (local_folder!=key && m_writeKeyInfo) {
744 sc=buildDescription("key",key,mergedNames);
745 if (sc.isFailure()) {
746 ATH_MSG_ERROR ("Could not merge towards merged description: "
747 << "key: " << key);
748 return( StatusCode::FAILURE);
749 }
750 }
751
752 // Add in symlink types
753 if (!symlinks.empty()) {
754 std::string symlinkTypes;
755 for (unsigned int i = 0; i < symlinks.size(); ++i) {
756 std::string type;
757 sc = m_clidSvc->getTypeNameOfID(symlinks[i], type);
758 if (sc.isFailure()) {
759 ATH_MSG_ERROR ("Could not get type name for symlink clid "
760 << symlinks[i]);
761 return( StatusCode::FAILURE);
762 }
763 else {
764 ATH_MSG_DEBUG ("adding symlink: clid, type "
765 << symlinks[i] << " " << type);
766 }
767 if (symlinkTypes.size()) symlinkTypes += ':';
768 symlinkTypes += type;
769 }
770 sc=buildDescription("symlinks", symlinkTypes, mergedNames);
771 if (sc.isFailure()) {
772 msg() << MSG::ERROR <<"Could not merge symlinks to merged description: "
773 << "symlink types: ";
774 for (unsigned int i = 0; i < symlinkTypes.size(); ++i) {
775 msg() << MSG::ERROR << symlinkTypes[i] << " ";
776 }
777 msg() << MSG::ERROR << endmsg;
778 return( StatusCode::FAILURE);
779 }
780 else {
781 ATH_MSG_DEBUG ("symlinks, merged names "
782 << symlinkTypes << " " << mergedNames);
783 }
784 }
785
786 // Type of time is defined by start/stop
787
788 // Some checks on the times:
789 if (!start.isValid() ||
790 !stop.isValid() ||
791 start.isTimestamp() != stop.isTimestamp() ||
792 start.isRunEvent() != stop.isRunEvent()) {
793 ATH_MSG_ERROR ("Invalid times: start isValid/isTimeStamp/isRunEvent "
794 << "addrHeader: " << address_header
795 << start.isValid() << " " << start.isTimestamp() << " "
796 << start.isRunEvent());
797 ATH_MSG_ERROR ("Invalid times: stop isValid/isTimeStamp/isRunEvent "
798 << "addrHeader: " << address_header
799 << stop.isValid() << " " << stop.isTimestamp() << " "
800 << stop.isRunEvent());
801 return( StatusCode::FAILURE);
802 }
803 bool isTimeStamp = false;
804 if (start.isTimestamp()) isTimeStamp = true;
805
806 if (isTimeStamp)
807 {
808 sc = buildDescription( "timeStamp", "time",
809 mergedNames );
810 }
811 else
812 {
813 sc = buildDescription( "timeStamp", "run-lumi",
814 mergedNames );
815 }
816 if (sc.isFailure()) {
817 ATH_MSG_ERROR ("Could not merge timeStamp flag towards merged description. ");
818 return( StatusCode::FAILURE);
819 }
820 // add <named/> for channels with names
821 if (storeAttrListColl && attrListColl!=0 &&
822 attrListColl->name_size()>0) mergedNames+="<named/>";
823
824 ATH_MSG_DEBUG (" create folder " << local_folder
825 << " with description " << mergedNames);
826
827 // Create folder
828
829 ATH_MSG_DEBUG ("Set attr list coll ptr " << attrListColl);
830
831 cool::RecordSpecification payloadSpec;
832 if (storeRef) {
833 // Folder with refs only:
834 // Payload specification - contains just a string
835 // assuming POOL refs will not be longer than 4000 chars
836 payloadSpec.extend("PoolRef",cool::StorageType::String4k);
837 }
838 else {
839 // Store AttributeList or a collection of AttributeLists
840 const coral::AttributeList* atr4spec=0;
841 if (storeAttrListColl) {
842
843 // Folder with CondAttrListCollection itself
844 // Get the attribute spec from the first element in the collection
845 if (0 == attrListColl) {
846 ATH_MSG_ERROR ("attrListColl not found. ");
847 return( StatusCode::FAILURE);
848 }
849
850 if (0 == attrListColl->size()) {
851 ATH_MSG_ERROR ("attrListColl is empty. ");
852 return( StatusCode::FAILURE);
853 }
854 // FIXME
855 ATH_MSG_DEBUG ("Size of AttrList collection" <<
856 attrListColl->size());
857
858 atr4spec=&((*attrListColl->begin()).second);
859 } else {
860 // folder with simple AttributeList
861 atr4spec=attrList;
862 ATH_MSG_DEBUG ("In simple atrlist branch");
863 }
864 ATH_MSG_DEBUG ("Pointer to atrList is " << atr4spec);
865 // construct COOL specification
866 for (coral::AttributeList::const_iterator itr=
867 atr4spec->begin();itr!=atr4spec->end();++itr) {
868 // extend specification with appropriate COOL type
869 // giving opportunity to override default choice
870 payloadSpec.extend(itr->specification().name(),
871 coralToCoolType(itr->specification().name(),
872 itr->specification().typeName()));
873 }
874 }
875 // create folder
876 cool::FolderVersioning::Mode version=
877 cool::FolderVersioning::MULTI_VERSION;
878 if (m_svFolder) {
879 version=cool::FolderVersioning::SINGLE_VERSION;
880 ATH_MSG_INFO ("Creating single version folder for "
881 << local_folder);
882 }
883 if (m_payloadTable)
884 ATH_MSG_INFO ("Creating separate payload table for "
885 << local_folder);
886 cool::FolderSpecification folderSpec(version,payloadSpec,cool::PayloadMode::SEPARATEPAYLOAD);
887 folder = db->createFolder(local_folder,folderSpec,
888 mergedNames,true);
889 ATH_MSG_DEBUG ("Creation of CondDBFolder " <<
890 local_folder << " done");
891
892 // create channels if needed - only for CondAttrListColl with names
893 if (storeAttrListColl && attrListColl!=0 &&
894 attrListColl->name_size()>0) {
895 ATH_MSG_DEBUG ("Naming " << attrListColl->name_size() <<
896 " channels in " << local_folder);
898 attrListColl->name_begin();
899 nitr!=attrListColl->name_end();++nitr) {
900 folder->createChannel(nitr->first,nitr->second);
901 }
902 }
903 }
904
905 // Print out stop/start ONLY for non-collections - collections
906 // have a per-channel start/stop
907 if (storeAttrListColl) {
908 ATH_MSG_DEBUG (" Global Start/stop time: "
909 << start << " " << stop << " Note: will be ignored for channels with differnt IOVs " );
910 }
911 else {
912 ATH_MSG_DEBUG (" Start/stop time " << start << " " << stop << " ");
913 }
914
915 // Convert IOVTime to ValidityKey
916 cool::ValidityKey ivStart = start.re_time();
917 cool::ValidityKey ivStop = stop.re_time();
918 if(start.isTimestamp()) {
919 ivStart = start.timestamp();
920 ivStop = stop.timestamp();
921 }
922
923 // get record specification of folder
924
925 const cool::RecordSpecification& rspec=folder->payloadSpecification();
926
927 if (storeAttrListColl) {
928 //
929 // Need to store multiple channels
930 //
931 // The policy for the IOV of each channel is to use the
932 // channel IOV already stored in the collection, if it is
933 // there. If it is not there, then use the global IOV.
934 //
935 if (storeRef) {
936 // Should NOT get here for a collection, signal error
937 ATH_MSG_ERROR ("Trying to store a ref for a CondAttrListCollection. ");
938 return( StatusCode::FAILURE);
939 }
940
941 ATH_MSG_DEBUG (" --> Storing Object( " << start << ", " << stop
942 << ", " << tag << " )");
943 ATH_MSG_DEBUG (" --> address: " << address_data);
944 // Loop over collection
945 CondAttrListCollection::const_iterator first = attrListColl->begin();
946 CondAttrListCollection::const_iterator last = attrListColl->end();
947 for (; first != last; ++first) {
948
949 // Copy from retrieved attribute list
950 const coral::AttributeList& payload = (*first).second;
951 // Get channel id
952 CondAttrListCollection::ChanNum chanNum = (*first).first;
953
954 // Check whether to use already stored IOV, or the
955 // global IOV
956 cool::ValidityKey ivStart1 = ivStart;
957 cool::ValidityKey ivStop1 = ivStop;
958 CondAttrListCollection::iov_const_iterator iovIt = attrListColl->chanIOVPair(chanNum);
959 std::ostringstream attr;
960 payload.toOutputStream( attr );
961 ATH_MSG_DEBUG (" --> ChanNum: " << chanNum << " Payload: " << attr.str());
962 if (!m_forceGlobalIOV && iovIt != attrListColl->iov_end()) {
963 const IOVRange& range = (*iovIt).second;
964 if(range.start().isTimestamp()) {
965 ivStart1 = range.start().timestamp();
966 ivStop1 = range.stop().timestamp();
967 }
968 else {
969 ivStart1 = range.start().re_time();
970 ivStop1 = range.stop().re_time();
971 }
972 ATH_MSG_DEBUG (" --> Start/stop time "
973 << range.start() << " " << range.stop() << " ");
974 }
975 else {
976 ATH_MSG_DEBUG (" --> Start/stop time "
977 << start << " " << stop << " ");
978 }
979
980 // Store address in folder with interval
981 cool::Record record(rspec,payload);
982 if (m_userTags && tag!="") {
983 ATH_MSG_DEBUG ("Object stored with user tag " << tag );
984 folder->storeObject( ivStart1,
985 ivStop1,
986 record,
987 chanNum,tag,!m_userTagsUH);
988 } else {
989 folder->storeObject( ivStart1,
990 ivStop1,
991 record,
992 chanNum);
993 }
994 }
995 }
996 else {
997 // Store a single channel
998 cool::Record record(rspec);
999 if (storeRef) {
1000 // PayLoad is ONLY the ref
1001 record["PoolRef"].setValue<std::string>(address_data);
1002 }
1003 else {
1004 // Copy from retrieved attribute list
1005 record=cool::Record(rspec,*attrList);
1006 }
1007
1008 // Store address in folder with interval
1009 if (m_userTags && tag!="") {
1010 ATH_MSG_DEBUG ("Object stored with user tag " << tag );
1011 folder->storeObject( ivStart,
1012 ivStop,
1013 record,0,tag,!m_userTagsUH);
1014 } else {
1015 folder->storeObject( ivStart,
1016 ivStop,
1017 record,0);
1018 }
1019
1020 ATH_MSG_DEBUG (" --> Stored Object( " << start << ", " << stop
1021 << ", " << tag << " )");
1022 ATH_MSG_DEBUG (" --> address: " << address_data);
1023 }
1024
1025 ATH_MSG_DEBUG (" storeData OK ");
1026
1027 // Now tag the folder if required
1028 if (!m_userTags) {
1029 if ("" == tag) {
1030 ATH_MSG_DEBUG (" tag is empty - folder is not being tagged ");
1031 }
1032 else {
1033 ATH_MSG_INFO (" Tagging HEAD of folder " << local_folder <<
1034 " with tag " << tag);
1035 try {
1036 folder->tagCurrentHead(tag,m_tagDescription);
1037 }
1038 catch ( cool::TagExists& e) {
1039 ATH_MSG_INFO ("Tag " << tag <<
1040 " exists - attempt to delete tag and retag HEAD");
1041 // first check this tag is really defined in THIS folder
1042 std::vector<std::string> taglist=folder->listTags();
1043 if (find(taglist.begin(),taglist.end(),tag)==
1044 taglist.end()) {
1045 ATH_MSG_ERROR ("Tag is defined in another folder - tag names must be global");
1046 } else if (folder->existsUserTag(tag)) {
1047 // this is a COOL user tag, in which case user
1048 // is trying to mix user and HEAD tags, not allowed in COOL1.3
1049 ATH_MSG_ERROR ("Tag " << tag <<
1050 " is already USER tag - cannot mix tagging modes");
1051 } else {
1052 try {
1053 folder->deleteTag(tag);
1054 folder->tagCurrentHead(tag,m_tagDescription);
1055 ATH_MSG_INFO ("Delete and retag succeeded");
1056 }
1057 catch ( cool::TagNotFound& e) {
1058 ATH_MSG_ERROR ("Delete and retag HEAD failed");
1059 }
1060 }
1061 }
1062 }
1063 }
1064 return StatusCode::SUCCESS;
1065 }
1066
1067 catch (std::exception& e) {
1068 ATH_MSG_ERROR ("*** COOL exception caught: " << e.what() );
1069 // << "\n"
1070 // << "*** error code: " << e.code()
1071 return StatusCode::FAILURE;
1072 }
1073
1074 //return StatusCode::SUCCESS;
1075}
1076
1077cool::StorageType::TypeId IOVRegistrationSvc::coralToCoolType(
1078 const std::string& parname,const std::string& coralName) const {
1079 // map coral type onto corresponding COOL storage type
1080 std::string coralType=coralName;
1081 // check for any overrides
1082 for (unsigned int i=0;i<m_overrideType.size();++i) {
1083 if (m_overrideName[i]==parname) {
1084 coralType=m_overrideType[i];
1085 ATH_MSG_INFO ("Override default type for attribute " <<
1086 parname << " - use " << coralType);
1087 }
1088 }
1089 // FIXME to include all CORAL/COOL types
1090 // give both the names of CORAL types, and COOL types which may get specified
1091 // as overrides
1092 if (coralType=="bool") return cool::StorageType::Bool;
1093 if (coralType=="UChar" || coralType=="unsigned char") return cool::StorageType::UChar;
1094 if (coralType=="Int16") return cool::StorageType::Int16;
1095 if (coralType=="UInt16") return cool::StorageType::UInt16;
1096 if (coralType=="Int32" || coralType=="int") return cool::StorageType::Int32;
1097 if (coralType=="UInt32" || coralType=="unsigned int") return cool::StorageType::UInt32;
1098 if (coralType=="UInt63" || coralType=="unsigned long long") return cool::StorageType::UInt63;
1099 if (coralType=="Int64" || coralType=="long long") return cool::StorageType::Int64;
1100 if (coralType=="Float" || coralType=="float") return cool::StorageType::Float;
1101 if (coralType=="Double" || coralType=="double") return cool::StorageType::Double;
1102 if (coralType=="String255") return cool::StorageType::String255;
1103 if (coralType=="String4k" || coralType=="string") return cool::StorageType::String4k;
1104 if (coralType=="String64k") return cool::StorageType::String64k;
1105 if (coralType=="String16M") return cool::StorageType::String16M;
1106 if (coralType=="blob" || coralType=="Blob64k")
1107 return cool::StorageType::Blob64k;
1108 if (coralType=="Blob16M") return cool::StorageType::Blob16M;
1109
1110 // if we get here, mapping is undefined
1111 ATH_MSG_FATAL ("No COOL mapping defined for CORAL type " << coralName);
1112 throw std::exception();
1113}
1114
1115
1116//--------------------------------------------------------------------------
1117
1118uint64_t IOVRegistrationSvc::timeToNano(const unsigned long int timesec) const
1119{
1120 // convert time specified in seconds to ns used by COOL
1121 // use the magic value MAXEVENT to signal full range
1122 if (timesec==IOVTime::MAXEVENT) {
1123 return IOVTime::MAXTIMESTAMP;
1124 } else {
1125 return static_cast<uint64_t>(timesec)*1000000000;
1126 }
1127}
1128
1129StatusCode IOVRegistrationSvc::buildDescription(const std::string& identifier,
1130 const std::string& value,
1131 std::string& description) const {
1132 // this routine was originally in IOVDbSvc, moved here as only client
1133 // buids an XML fragment of form <identifier>value</identifier>
1134 if (identifier.empty() || value.empty()) {
1135 ATH_MSG_ERROR ("Identifier or value is null.");
1136 return StatusCode::FAILURE;
1137 }
1138 description = "<"+identifier+">"+value+"</"+identifier+">"+description;
1139 return StatusCode::SUCCESS;
1140}
1141
1142StatusCode IOVRegistrationSvc::splitAddress(const std::string& address,
1143 std::string& address_header,
1144 std::string& address_data ) const {
1145 // this routine was originally in IOVDbSvc, moved here as only client
1146 // Deals with address of form
1147 // <address_header service_type="256" clid="1238547719" /> POOLContainer_CondAttrListCollection][CLID=x
1148 // return header as part up to and including />, trailer as rest
1149
1150 std::string::size_type p1=address.find(" />");
1151 if (p1!=std::string::npos) {
1152 address_header=address.substr(0,p1+3);
1153 address_data=address.substr(p1+4);
1154 return StatusCode::SUCCESS;
1155 } else {
1156 return StatusCode::FAILURE;
1157 }
1158}
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_FATAL(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
This file contains the class definition for the AthenaAttrListAddress class.
This file contains the class definition for the CondAttrListCollAddress class.
This file defines the class for a collection of AttributeLists where each one is associated with a ch...
uint32_t CLID
The Class ID type.
This is an interface to a tool used to register conditions objects in the Interval of Validity (IOV) ...
static Double_t sc
An AttributeList represents a logical row of attributes in a metadata table.
This class provides an IOpaqueAddress/GenericAddress which can hold a pointer to a CondAttrListCollec...
CondAttrListCollection * attrListColl()
Access to AttributeList.
This class is a collection of AttributeLists where each one is associated with a channel number.
const_iterator end() const
name_const_iterator name_begin() const
Access to Chan/Name pairs via iterators.
name_size_type name_size() const
number of Chan/Name pairs
const_iterator begin() const
Access to Chan/AttributeList pairs via iterators.
iov_const_iterator iov_end() const
name_const_iterator name_end() const
size_type size() const
number of Chan/AttributeList pairs
iov_const_iterator chanIOVPair(ChanNum chanNum) const
Access to Chan/IOV pairs via channel number: returns map iterator.
ChanAttrListMap::const_iterator const_iterator
ChanNameMap::const_iterator name_const_iterator
ChanIOVMap::const_iterator iov_const_iterator
Validity Range object.
Definition IOVRange.h:30
Gaudi::Property< bool > m_writeKeyInfo
Gaudi::Property< bool > m_recreateFolders
Gaudi::Property< bool > m_forceGlobalIOV
IOVRegistrationSvc(const std::string &name, ISvcLocator *svc)
ServiceHandle< IAddressCreator > m_persSvc
virtual StatusCode initialize()
Initialize AlgTool.
Gaudi::Property< std::string > m_tagDescription
virtual StatusCode buildDescription(const std::string &identifier, const std::string &value, std::string &description) const
Build the folder description field add in front of the description the value with identifier-markups.
ServiceHandle< IIOVCondDbSvc > m_iov_db
Gaudi::Property< bool > m_userTagsUH
Gaudi::Property< bool > m_userTags
Gaudi::Property< unsigned long > m_beginTime
ServiceHandle< IClassIDSvc > m_clidSvc
uint64_t timeToNano(const unsigned long int timesec) const
StatusCode registerIOVCOOL(const std::string &typeName, const std::string &key, const std::string &folderName, const std::string &tag, const IOVTime &begin, const IOVTime &end) const
Gaudi::Property< bool > m_timeStamp
ServiceHandle< StoreGateSvc > m_detStore
Gaudi::Property< bool > m_payloadTable
Gaudi::Property< unsigned int > m_endLB
Gaudi::Property< unsigned int > m_beginLB
Gaudi::Property< std::string > m_tag
virtual StatusCode finalize()
Finalize AlgTool.
Gaudi::Property< std::vector< std::string > > m_overrideName
virtual StatusCode registerIOV(const std::string &typeName) const
Register IOV DB for an object given its typeName - run/LB numbers interval or times interval and tag ...
Gaudi::Property< unsigned int > m_beginRun
Gaudi::Property< unsigned int > m_endRun
Gaudi::Property< std::vector< std::string > > m_overrideType
Gaudi::Property< bool > m_svFolder
Gaudi::Property< unsigned long > m_endTime
virtual const InterfaceID & type() const
Service type.
cool::StorageType::TypeId coralToCoolType(const std::string &parname, const std::string &coralName) const
StatusCode splitAddress(const std::string &address, std::string &address_header, std::string &address_data) const
Split address in its header and data parts.
Basic time unit for IOVSvc.
Definition IOVTime.h:33
static constexpr uint64_t MAXTIMESTAMP
Definition IOVTime.h:58
static constexpr uint32_t MAXEVENT
Definition IOVTime.h:51
std::string description
glabal timer - how long have I taken so far?
Definition hcg.cxx:91
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138
MsgStream & msg
Definition testRead.cxx:32