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