Skip to content

Commit

Permalink
Added TObject2Json (#5)
Browse files Browse the repository at this point in the history
Move TObject2Json to QualityControl repo
  • Loading branch information
awegrzyn authored Mar 5, 2018
1 parent 49f9cf5 commit 1d1c54d
Show file tree
Hide file tree
Showing 12 changed files with 721 additions and 0 deletions.
6 changes: 6 additions & 0 deletions Framework/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ if(ROOT_FOUND) # TODO remove this once we have our own repo
TEST_SRCS ${TEST_SRCS}
)

O2_GENERATE_EXECUTABLE(
EXE_NAME "tobject2json"
SOURCES "src/TObject2JsonServer.cxx" "src/TObject2Json.cxx" "src/TObject2JsonMySql.cxx" "src/TObject2JsonFactory.cxx"
MODULE_LIBRARY_NAME ${LIBRARY_NAME}
BUCKET_NAME "o2_qc_tobject2json"
)
endif()

# Install extra scripts
Expand Down
108 changes: 108 additions & 0 deletions Framework/src/TObject2Json.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// Copyright CERN and copyright holders of ALICE O2. This software is
// distributed under the terms of the GNU General Public License v3 (GPL
// Version 3), copied verbatim in the file "COPYING".
//
// See http://alice-o2.web.cern.ch/license for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file TObejct2Json.cxx
/// \author Vladimir Kosmala
/// \author Adam Wegrzynek
///

// TObject2Json
#include "TObject2Json.h"
#include "TObject2JsonMySql.h"
#include "QualityControl/QcInfoLogger.h"

#include <chrono>
#include <thread>

// ZMQ
#include <zmq.h>

// Boost
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace o2::quality_control::core;
using namespace std::string_literals;

namespace o2 {
namespace quality_control {
namespace tobject_to_json {

TObject2Json::TObject2Json(std::unique_ptr<Backend> backend, std::string zeromqUrl)
: mBackend(std::move(backend))
{
mContext = zmq_ctx_new ();
mSocket = zmq_socket (mContext, ZMQ_REP);
int rc = zmq_bind (mSocket, zeromqUrl.c_str());
if (rc != 0) {
throw std::runtime_error("Couldn't bind the socket "s + zmq_strerror(zmq_errno()));
}
QcInfoLogger::GetInstance() << "ZeroMQ server: Socket bound " << zeromqUrl << infologger::endm;
}

string TObject2Json::handleRequest(string request)
{
if (request.length() == 0) {
QcInfoLogger::GetInstance() << "Empty request received, ignoring..." << infologger::endm;
return "";
}

// Split arguments with space
vector<string> parts;
boost::split(parts, request, boost::is_any_of(" "));

if (parts.size() != 2) {
QcInfoLogger::GetInstance() << "! Service requires 2 arguments" << infologger::endm;
}

string agentName = parts[0];
string objectName = parts[1];
try {
return mBackend->getJsonObject(agentName, objectName);
} catch (const std::exception& error) {
return "500 unhandled error";
}
}

void TObject2Json::start()
{
while(1) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
// Wait for next request
zmq_msg_t messageReq;
zmq_msg_init(&messageReq);
int size = zmq_msg_recv(&messageReq, mSocket, 0);
if (size == -1) {
QcInfoLogger::GetInstance() << "Unable to read socket: " << zmq_strerror(zmq_errno()) << infologger::endm;
zmq_msg_close(&messageReq);
continue;
}
// Process message
string request((const char*)zmq_msg_data(&messageReq), size);
zmq_msg_close(&messageReq);
QcInfoLogger::GetInstance() << "Received request (" << request << ")" << infologger::endm;
string response = handleRequest(request);
QcInfoLogger::GetInstance() << "Response generated" << infologger::endm;
// Send back response
zmq_msg_t messageRep;
zmq_msg_init_size(&messageRep, response.size());
memcpy(zmq_msg_data(&messageRep), response.data(), response.size());
size = zmq_msg_send(&messageRep, mSocket, 0);
if (size == -1) {
QcInfoLogger::GetInstance() << "Unable to write socket: " << zmq_strerror(zmq_errno()) << infologger::endm;
}
zmq_msg_close(&messageRep);
}
}

} // namespace tobject_to_json
} // namespace quality_control
} // namespace o2
56 changes: 56 additions & 0 deletions Framework/src/TObject2Json.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright CERN and copyright holders of ALICE O2. This software is
// distributed under the terms of the GNU General Public License v3 (GPL
// Version 3), copied verbatim in the file "COPYING".
//
// See http://alice-o2.web.cern.ch/license for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file TObejct2Json.h
/// \author Vladimir Kosmala
/// \author Adam Wegrzynek
///

#ifndef QUALITYCONTROL_TOBJECT2JSON_H
#define QUALITYCONTROL_TOBJECT2JSON_H

#include "TObject2JsonBackend.h"

using o2::quality_control::repository::MySqlDatabase;

namespace o2 {
namespace quality_control {
namespace tobject_to_json {

/// \brief Converts ROOT objects into JSON format, readable by JSROOT
class TObject2Json
{
public:
/// Creates backend and binds ZeroMQ socket
TObject2Json(std::unique_ptr<Backend> backend, std::string zeromqUrl);

/// Listens to the ZeroMQ server endpoint
void start();

private:
/// MySQL client instance from QualityControl framework
std::unique_ptr<Backend> mBackend;

/// ZeroMQ context
void *mContext;

/// ZeroMQ server socket
void *mSocket;

// Handle ZeroMQ request
std::string handleRequest(std::string message);
};

} // namespace tobject_to_json {
} // namespace quality_control
} // namespace o2

#endif // QUALITYCONTROL_TOBJECT2JSON_H
47 changes: 47 additions & 0 deletions Framework/src/TObject2JsonBackend.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright CERN and copyright holders of ALICE O2. This software is
// distributed under the terms of the GNU General Public License v3 (GPL
// Version 3), copied verbatim in the file "COPYING".
//
// See http://alice-o2.web.cern.ch/license for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file Backend.h
/// \author Vladimir Kosmala
/// \author Adam Wegrzynek
///

#ifndef QUALITYCONTROL_TOBJECT2JSON_BACKEND_H
#define QUALITYCONTROL_TOBJECT2JSON_BACKEND_H

// QualityControl
#include "QualityControl/MySqlDatabase.h"

using o2::quality_control::repository::MySqlDatabase;

namespace o2 {
namespace quality_control {
namespace tobject_to_json {

/// \brief Converts ROOT objects into JSON format which is readable by JSROOT
class Backend
{
public:
/// Default constructor
Backend() = default;

/// Default destructor
virtual ~Backend() = default;

/// Gets TObject from database and returns the JSON equivalent
virtual std::string getJsonObject(std::string agentName, std::string objectName) = 0;
};

} // namespace tobject_to_json
} // namespace quality_control
} // namespace o2

#endif // QUALITYCONTROL_TOBJECT2JSON_MYSQL_H
54 changes: 54 additions & 0 deletions Framework/src/TObject2JsonFactory.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright CERN and copyright holders of ALICE O2. This software is
// distributed under the terms of the GNU General Public License v3 (GPL
// Version 3), copied verbatim in the file "COPYING".
//
// See http://alice-o2.web.cern.ch/license for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file TObject2JsonFactory.cxx
/// \author Adam Wegrzynek
///

#include "TObject2JsonFactory.h"
#include "TObject2Json.h"
#include "TObject2JsonMySql.h"
#include "external/UriParser.h"

namespace o2 {
namespace quality_control {
namespace tobject_to_json {


auto getMySql(const http::url& uri) {
unsigned int port = (uri.port == 0) ? 3306 : uri.port;
std::string database = uri.path;
database.erase(database.begin(), database.begin() + 1);
return std::make_unique<backends::MySql>(uri.host, port, database, uri.user, uri.password);
}


std::unique_ptr<TObject2Json> TObject2JsonFactory::Get(std::string url, std::string zeromqUrl) {
static const std::map<std::string, std::function<std::unique_ptr<Backend>(const http::url&)>> map = {
{"mysql", getMySql}
};

http::url parsedUrl = http::ParseHttpUrl(url);
if (parsedUrl.protocol.empty()) {
throw std::runtime_error("Ill-formed URI");
}

auto iterator = map.find(parsedUrl.protocol);
if (iterator != map.end()) {
return std::make_unique<TObject2Json>(iterator->second(parsedUrl), zeromqUrl);
} else {
throw std::runtime_error("Unrecognized backend " + parsedUrl.protocol);
}
}

} // namespace tobject_to_json
} // namespace quality_control
} // namespace o2
47 changes: 47 additions & 0 deletions Framework/src/TObject2JsonFactory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright CERN and copyright holders of ALICE O2. This software is
// distributed under the terms of the GNU General Public License v3 (GPL
// Version 3), copied verbatim in the file "COPYING".
//
// See http://alice-o2.web.cern.ch/license for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file TObejct2Json.h
/// \author Adam Wegrzynek
///

#ifndef QUALITYCONTROL_TOBJECT2JSON_FACTORY_H
#define QUALITYCONTROL_TOBJECT2JSON_FACTORY_H

#include "TObject2Json.h"
#include "TObject2JsonBackend.h"

namespace o2 {
namespace quality_control {
namespace tobject_to_json {

/// Creates and condifures TObject2Json object
class TObject2JsonFactory
{
public:
/// Disables copy constructor
TObject2JsonFactory & operator=(const TObject2JsonFactory&) = delete;
TObject2JsonFactory(const TObject2JsonFactory&) = delete;

/// Creates an instance of TObject2Json
/// \return renerence to TObject2Json object
static std::unique_ptr<TObject2Json> Get(std::string url, std::string zeromqUrl);

private:
/// Private constructor disallows to create instance of Factory
TObject2JsonFactory() = default;
};

} // namespace tobject_to_json {
} // namespace quality_control
} // namespace o2

#endif // QUALITYCONTROL_TOBJECT2JSON_FACTORY_H
55 changes: 55 additions & 0 deletions Framework/src/TObject2JsonMySql.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright CERN and copyright holders of ALICE O2. This software is
// distributed under the terms of the GNU General Public License v3 (GPL
// Version 3), copied verbatim in the file "COPYING".
//
// See http://alice-o2.web.cern.ch/license for full licensing information.
//
// In applying this license CERN does not waive the privileges and immunities
// granted to it by virtue of its status as an Intergovernmental Organization
// or submit itself to any jurisdiction.

///
/// \file MySQL.cxx
/// \author Vladimir Kosmala
/// \author Adam Wegrzynek
///

#include "TObject2JsonMySql.h"
// QualityControl
#include "QualityControl/MySqlDatabase.h"
#include "QualityControl/MonitorObject.h"
#include "QualityControl/QcInfoLogger.h"

// ROOT
#include "TBufferJSON.h"

using o2::quality_control::repository::MySqlDatabase;
using o2::quality_control::core::MonitorObject;
using o2::quality_control::core::QcInfoLogger;

namespace o2 {
namespace quality_control {
namespace tobject_to_json {
namespace backends {

MySql::MySql(std::string host, unsigned int port, std::string database, std::string username, std::string password)
{
host += ":" + std::to_string(port);
mSqlClient = std::make_unique<MySqlDatabase>();
mSqlClient->connect(host, database, username, password);
QcInfoLogger::GetInstance() << "MySQL backend created: " << host << "/" << database << infologger::endm;
}

std::string MySql::getJsonObject(std::string agentName, std::string objectName)
{
std::unique_ptr<MonitorObject> monitor(mSqlClient->retrieve(agentName, objectName));
std::unique_ptr<TObject> obj(monitor->getObject());
monitor->setIsOwner(false);
TString json = TBufferJSON::ConvertToJSON(obj.get());
return json.Data();
}

} // namespace backends
} // namespace tobject_to_json
} // namespace quality_control
} // namespace o2
Loading

0 comments on commit 1d1c54d

Please sign in to comment.