Skip to content

Commit f2132b2

Browse files
committed
CCDB: generalization; refactoring; new Server query example
* Introduction of TObjectWrapper to be able to put any class with a dictionary inside a Condition (no more required to be of TObject type initially) * Unit test to read/write a non TObject class * Some renaming of functions to better express the return value of "Condition" rather than "Object" * The Backend::Unpack function now returns a condition; Otherwise the user can not get hold of the unpacked blob * A new example demonstrating that we can quere the conditions-server from any (even non-device) user code; The example is very prototypic @authors: J. Wiechula, S. Wenzel
1 parent 4d58d5a commit f2132b2

18 files changed

Lines changed: 276 additions & 21 deletions

CCDB/CMakeLists.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ set(HEADERS
3939
include/${MODULE_NAME}/ObjectHandler.h
4040
include/${MODULE_NAME}/Storage.h
4141
include/${MODULE_NAME}/XmlHandler.h
42+
test/TestClass.h
4243
)
4344

4445
Set(NO_DICT_SRCS
@@ -57,11 +58,13 @@ O2_GENERATE_LIBRARY()
5758
Set(Exe_Names
5859
conditions-server
5960
conditions-client
61+
standalone-client
6062
)
6163

6264
Set(Exe_Source
6365
src/runConditionsServer.cxx
6466
src/runConditionsClient.cxx
67+
test/testQueryServerStandalone.cxx
6568
)
6669

6770
list(LENGTH Exe_Names _length)
@@ -87,3 +90,15 @@ install(
8790
example/fill_local_ocdb.C
8891
DESTINATION bin/config
8992
)
93+
94+
set(TEST_SRCS
95+
test/testWriteReadAny.cxx
96+
)
97+
98+
O2_GENERATE_TESTS(
99+
BUCKET_NAME ${BUCKET_NAME}
100+
MODULE_LIBRARY_NAME ${MODULE_NAME}
101+
TEST_SRCS ${TEST_SRCS}
102+
)
103+
104+

CCDB/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ conditions-server --id parmq-server --mq-config <installation directory>/bin/con
2626
conditions-client --id parmq-client --mq-config <installation directory>/bin/config/conditions-client.json --data-source OCDB --object-path <installation directory>/bin/config/O2CDB
2727
```
2828

29+
* We can also query the running conditions-server using any user code as
30+
demonstrated in `standalone-client` which works for an O2CDB
31+
generated from the unit test `testWriteReadAny`
32+
2933
### Riak backend
3034

3135
To run the MQ server-client example with the MQ server executing PUT or GET commands to a Riak cluster through an MQ broker, the steps below should be followed:

CCDB/config/conditions-client.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
{
1212
"type": "push",
1313
"method": "connect",
14-
"address": "tcp://localhost:5005",
14+
"address": "tcp://localhost:25005",
1515
"sndBufSize": "200",
1616
"rcvBufSize": "1000",
1717
"rateLogging": "0"
@@ -24,7 +24,7 @@
2424
{
2525
"type": "req",
2626
"method": "connect",
27-
"address": "tcp://localhost:5006",
27+
"address": "tcp://localhost:25006",
2828
"sndBufSize": "1000",
2929
"rcvBufSize": "1000",
3030
"rateLogging": "0"

CCDB/config/conditions-server.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
{
1212
"type": "pull",
1313
"method": "bind",
14-
"address": "tcp://*:5005",
14+
"address": "tcp://*:25005",
1515
"sndBufSize": "1000",
1616
"rcvBufSize": "1000",
1717
"rateLogging": "0"
@@ -24,7 +24,7 @@
2424
{
2525
"type": "rep",
2626
"method": "bind",
27-
"address": "tcp://*:5006",
27+
"address": "tcp://*:25006",
2828
"sndBufSize": "1000",
2929
"rcvBufSize": "1000",
3030
"rateLogging": "0"

CCDB/include/CCDB/Backend.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
namespace o2 {
2828
namespace CDB {
2929

30+
class Condition;
31+
3032
class Backend {
3133
public:
3234
virtual ~Backend()= default;
@@ -35,7 +37,7 @@ class Backend {
3537
virtual void Pack(const std::string& path, const std::string& key, std::string*& messageString) = 0;
3638

3739
/// UnPack
38-
virtual void UnPack(std::unique_ptr<FairMQMessage> msg) = 0;
40+
virtual Condition* UnPack(std::unique_ptr<FairMQMessage> msg) = 0;
3941

4042
/// Serializes a key (and optionally value) to an std::string using Protocol Buffers
4143
void Serialize(std::string*& messageString, const std::string& key, const std::string& operationType,

CCDB/include/CCDB/BackendOCDB.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class BackendOCDB : public Backend {
3434
void Pack(const std::string& path, const std::string& key, std::string*& messageString) override;
3535

3636
/// Parses an incoming message from the CCDB server and prints the metadata of the included object
37-
void UnPack(std::unique_ptr<FairMQMessage> msg) override;
37+
Condition* UnPack(std::unique_ptr<FairMQMessage> msg) override;
3838
};
3939
}
4040
}

CCDB/include/CCDB/BackendRiak.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class BackendRiak : public Backend {
4040
void Pack(const std::string& path, const std::string& key, std::string*& messageString) override;
4141

4242
/// Deserializes and uncompresses an incoming message from the CCDB server
43-
void UnPack(std::unique_ptr<FairMQMessage> msg) override;
43+
Condition* UnPack(std::unique_ptr<FairMQMessage> msg) override;
4444
};
4545
}
4646
}

CCDB/include/CCDB/Condition.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "CCDB/ConditionId.h" // for ConditionId
1818
#include "CCDB/ConditionMetaData.h" // for ConditionMetaData
1919
#include "CCDB/IdPath.h" // for IdPath
20+
#include <CCDB/TObjectWrapper.h>
2021
#include "Rtypes.h" // for Int_t, kFALSE, Bool_t, etc
2122
#include "TObject.h" // for TObject
2223
#include "TString.h" // for TString
@@ -109,6 +110,19 @@ class Condition : public TObject
109110
return mObject;
110111
};
111112

113+
/// retrieve object as specified type
114+
/// return false if failed/true otherwise
115+
template<typename T>
116+
bool getObjectAs(T *& obj) {
117+
obj = nullptr;
118+
// test if saved object was a wrapped object
119+
if(auto wrapped = dynamic_cast<TObjectWrapper<T>*>(mObject)) {
120+
obj = wrapped->getObj();
121+
return true;
122+
}
123+
return false;
124+
}
125+
112126
void setConditionMetaData(ConditionMetaData *metaData)
113127
{
114128
mConditionMetaData = metaData;

CCDB/include/CCDB/Manager.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <cstddef> // for NULL
1818
#include "Rtypes.h" // for Int_t, Bool_t, kFALSE, kTRUE, ClassDef, etc
1919
#include "TString.h" // for TString
20+
#include <CCDB/TObjectWrapper.h>
2021

2122
class TFile;
2223
namespace o2 { namespace CDB { class Condition; }} // lines 20-20
@@ -133,11 +134,11 @@ class Manager : public TObject
133134
return mOcdbUploadMode;
134135
}
135136

136-
Condition *getObject(const ConditionId &query, Bool_t forceCaching = kFALSE);
137+
Condition *getCondition(const ConditionId &query, Bool_t forceCaching = kFALSE);
137138

138-
Condition *getObject(const IdPath &path, Int_t runNumber = -1, Int_t version = -1, Int_t subVersion = -1);
139+
Condition *getCondition(const IdPath &path, Int_t runNumber = -1, Int_t version = -1, Int_t subVersion = -1);
139140

140-
Condition *getObject(const IdPath &path, const IdRunRange &runRange, Int_t version = -1, Int_t subVersion = -1);
141+
Condition *getCondition(const IdPath &path, const IdRunRange &runRange, Int_t version = -1, Int_t subVersion = -1);
141142

142143
Condition *getConditionFromSnapshot(const char *path);
143144

@@ -151,7 +152,13 @@ class Manager : public TObject
151152

152153
Bool_t putObject(TObject *object, const ConditionId &id, ConditionMetaData *metaData, const char *mirrors = "");
153154

154-
Bool_t putObject(Condition *entry, const char *mirrors = "");
155+
template <typename T>
156+
Bool_t putObjectAny(T *ptr, const ConditionId &id, ConditionMetaData *metaData, const char *mirrors = "") {
157+
TObjectWrapper<T> local(ptr);
158+
return putObject(&local, id, metaData, mirrors);
159+
}
160+
161+
Bool_t putCondition(Condition *entry, const char *mirrors = "");
155162

156163
void setCacheFlag(Bool_t cacheFlag)
157164
{

CCDB/include/CCDB/TObjectWrapper.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Copyright CERN and copyright holders of ALICE O2. This software is
2+
// distributed under the terms of the GNU General Public License v3 (GPL
3+
// Version 3), copied verbatim in the file "COPYING".
4+
//
5+
// See http://alice-o2.web.cern.ch/license for full licensing information.
6+
//
7+
// In applying this license CERN does not waive the privileges and immunities
8+
// granted to it by virtue of its status as an Intergovernmental Organization
9+
// or submit itself to any jurisdiction.
10+
11+
#ifndef O2_TOBJECTWRAPPER_H
12+
#define O2_TOBJECTWRAPPER_H
13+
#include <TClass.h>
14+
#include <TObject.h>
15+
#include <cxxabi.h>
16+
#include <iostream>
17+
#include <memory>
18+
#include <stdexcept>
19+
#include <typeinfo>
20+
21+
namespace o2
22+
{
23+
// anonymous namespace to prevent usage outside of this file
24+
namespace
25+
{
26+
/// utility function to demangle cxx type names
27+
std::string demangle(const char* name)
28+
{
29+
int status = -4; // some arbitrary value to eliminate the compiler warning
30+
std::unique_ptr<char, void (*)(void*)> res{ abi::__cxa_demangle(name, nullptr, nullptr, &status), std::free };
31+
return (status == 0) ? res.get() : name;
32+
}
33+
} // end anonymous namespace
34+
35+
/// A wrapper class to easily promote any type to a TObject
36+
/// does not take ownership of wrapped object and should not be used
37+
/// in tight loops since construction expensive
38+
template <typename T>
39+
class TObjectWrapper : public TObject
40+
{
41+
public:
42+
TObjectWrapper(T* obj) : mObj(obj), TObject()
43+
{
44+
// make sure that a dictionary for this wrapper exists
45+
auto& t = typeid(*this);
46+
std::string message("Need dicionary for type ");
47+
auto typestring = demangle(t.name());
48+
message.append(typestring);
49+
message.append("\n");
50+
auto hasdict = TClass::HasDictionarySelection(typestring.c_str());
51+
if (!hasdict) {
52+
throw std::runtime_error(message);
53+
}
54+
}
55+
56+
TObjectWrapper() : TObjectWrapper(nullptr) {}
57+
void setObj(T* obj) { mObj = obj; }
58+
T* getObj() const { return mObj; }
59+
~TObjectWrapper() override = default;
60+
61+
private:
62+
T* mObj;
63+
ClassDefOverride(TObjectWrapper, 1);
64+
};
65+
}
66+
67+
#endif

0 commit comments

Comments
 (0)