diff --git a/Framework/CMakeLists.txt b/Framework/CMakeLists.txt index e70d13c3c2ad8..8033936b9abab 100644 --- a/Framework/CMakeLists.txt +++ b/Framework/CMakeLists.txt @@ -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 diff --git a/Framework/src/TObject2Json.cxx b/Framework/src/TObject2Json.cxx new file mode 100644 index 0000000000000..3ad67e0a148ad --- /dev/null +++ b/Framework/src/TObject2Json.cxx @@ -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 +#include + +// ZMQ +#include + +// Boost +#include + +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, 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 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 diff --git a/Framework/src/TObject2Json.h b/Framework/src/TObject2Json.h new file mode 100644 index 0000000000000..fe5404dd20982 --- /dev/null +++ b/Framework/src/TObject2Json.h @@ -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, std::string zeromqUrl); + + /// Listens to the ZeroMQ server endpoint + void start(); + + private: + /// MySQL client instance from QualityControl framework + std::unique_ptr 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 diff --git a/Framework/src/TObject2JsonBackend.h b/Framework/src/TObject2JsonBackend.h new file mode 100644 index 0000000000000..f86cd5ee7edd7 --- /dev/null +++ b/Framework/src/TObject2JsonBackend.h @@ -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 diff --git a/Framework/src/TObject2JsonFactory.cxx b/Framework/src/TObject2JsonFactory.cxx new file mode 100644 index 0000000000000..3aa509d811a5e --- /dev/null +++ b/Framework/src/TObject2JsonFactory.cxx @@ -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(uri.host, port, database, uri.user, uri.password); +} + + +std::unique_ptr TObject2JsonFactory::Get(std::string url, std::string zeromqUrl) { + static const std::map(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(iterator->second(parsedUrl), zeromqUrl); + } else { + throw std::runtime_error("Unrecognized backend " + parsedUrl.protocol); + } +} + +} // namespace tobject_to_json +} // namespace quality_control +} // namespace o2 diff --git a/Framework/src/TObject2JsonFactory.h b/Framework/src/TObject2JsonFactory.h new file mode 100644 index 0000000000000..0330555004b07 --- /dev/null +++ b/Framework/src/TObject2JsonFactory.h @@ -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 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 diff --git a/Framework/src/TObject2JsonMySql.cxx b/Framework/src/TObject2JsonMySql.cxx new file mode 100644 index 0000000000000..562142233cb50 --- /dev/null +++ b/Framework/src/TObject2JsonMySql.cxx @@ -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(); + 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 monitor(mSqlClient->retrieve(agentName, objectName)); + std::unique_ptr 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 diff --git a/Framework/src/TObject2JsonMySql.h b/Framework/src/TObject2JsonMySql.h new file mode 100644 index 0000000000000..75295e2ac1b94 --- /dev/null +++ b/Framework/src/TObject2JsonMySql.h @@ -0,0 +1,52 @@ +// 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_MYSQL_H +#define QUALITYCONTROL_TOBJECT2JSON_MYSQL_H + +#include "TObject2JsonBackend.h" + +// QualityControl +#include "QualityControl/MySqlDatabase.h" + +using o2::quality_control::repository::MySqlDatabase; + +namespace o2 { +namespace quality_control { +namespace tobject_to_json { +namespace backends { + +/// Takes TObject from MySQL database and returns JSON formatted object +class MySql final : public Backend +{ + public: + // Connects to MySQL database + MySql(std::string host, unsigned int port, std::string database, std::string username, std::string password); + + /// Gets TObject from database and returns the JSON equivalent + std::string getJsonObject(std::string agentName, std::string objectName) override; + + private: + /// MySQL client instance + std::unique_ptr mSqlClient; +}; + +} // namespace backends { +} // namespace tobject_to_json +} // namespace quality_control +} // namespace o2 + +#endif // QUALITYCONTROL_TOBJECT2JSON_MYSQL_H diff --git a/Framework/src/TObject2JsonServer.cxx b/Framework/src/TObject2JsonServer.cxx new file mode 100644 index 0000000000000..7fc63526e228a --- /dev/null +++ b/Framework/src/TObject2JsonServer.cxx @@ -0,0 +1,33 @@ +/// +/// \file TObject2JsonServer.cxx +/// \author Adam Wegrzynek +/// + +// TObject2Json +#include "TObject2JsonFactory.h" +#include + +using o2::quality_control::tobject_to_json::TObject2JsonFactory; + +int main(int argc, char *argv[]) +{ + boost::program_options::variables_map vm; + boost::program_options::options_description desc("Allowed options"); + desc.add_options() + ("backend", boost::program_options::value()->required(), "Backend URL, eg.: mysql://:@:/") + ("zeromq-server", boost::program_options::value()->required(), "ZeroMQ server endpoint, eg.: tcp://:") + ; + try { + boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm); + boost::program_options::notify(vm); + } catch (...) { + std::cout << desc << std::endl; + return 1; + } + std::string backend = vm["backend"].as(); + std::string zeromq = vm["zeromq-server"].as(); + + auto converter = TObject2JsonFactory::Get(backend, zeromq); + converter->start(); + return 0; +} diff --git a/Framework/src/external/UriParser.h b/Framework/src/external/UriParser.h new file mode 100644 index 0000000000000..7d225bbc0ac89 --- /dev/null +++ b/Framework/src/external/UriParser.h @@ -0,0 +1,101 @@ +/* +Copyright (c) 2013 Covenant Eyes + +Permission is hereby granted, free of charge, to any person obtaining a copy of this +software and associated documentation files (the "Software"), to deal in the Software +without restriction, including without limitation the rights to use, copy, modify, +merge, publish, distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be included in all copies +or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef ALICEO2_HTTPPARSER_H +#define ALICEO2_HTTPPARSER_H + +#include +#include +#include + + +namespace http { + struct url { + std::string protocol, user, password, host, path, search; + int port; + }; + + + //--- Helper Functions -------------------------------------------------------------~ + static inline std::string TailSlice(std::string &subject, std::string delimiter, bool keep_delim=false) { + // Chops off the delimiter and everything that follows (destructively) + // returns everything after the delimiter + auto delimiter_location = subject.find(delimiter); + auto delimiter_length = delimiter.length(); + std::string output = ""; + + if (delimiter_location < std::string::npos) { + auto start = keep_delim ? delimiter_location : delimiter_location + delimiter_length; + auto end = subject.length() - start; + output = subject.substr(start, end); + subject = subject.substr(0, delimiter_location); + } + return output; + } + + static inline std::string HeadSlice(std::string &subject, std::string delimiter) { + // Chops off the delimiter and everything that precedes (destructively) + // returns everthing before the delimeter + auto delimiter_location = subject.find(delimiter); + auto delimiter_length = delimiter.length(); + std::string output = ""; + if (delimiter_location < std::string::npos) { + output = subject.substr(0, delimiter_location); + subject = subject.substr(delimiter_location + delimiter_length, subject.length() - (delimiter_location + delimiter_length)); + } + return output; + } + + + //--- Extractors -------------------------------------------------------------------~ + static inline int ExtractPort(std::string &hostport) { + int port; + std::string portstring = TailSlice(hostport, ":"); + try { port = atoi(portstring.c_str()); } + catch (std::exception e) { port = -1; } + return port; + } + + static inline std::string ExtractPath(std::string &in) { return TailSlice(in, "/", true); } + static inline std::string ExtractProtocol(std::string &in) { return HeadSlice(in, "://"); } + static inline std::string ExtractSearch(std::string &in) { return TailSlice(in, "?"); } + static inline std::string ExtractPassword(std::string &userpass) { return TailSlice(userpass, ":"); } + static inline std::string ExtractUserpass(std::string &in) { return HeadSlice(in, "@"); } + + + //--- Public Interface -------------------------------------------------------------~ + static inline url ParseHttpUrl(std::string &in) { + url ret; + ret.port = -1; + + ret.protocol = ExtractProtocol(in); + ret.search = ExtractSearch(in); + ret.path = ExtractPath(in); + std::string userpass = ExtractUserpass(in); + ret.password = ExtractPassword(userpass); + ret.user = userpass; + ret.port = ExtractPort(in); + ret.host = in; + + return ret; + } +} +#endif diff --git a/cmake/FindZeroMQ.cmake b/cmake/FindZeroMQ.cmake new file mode 100644 index 0000000000000..8cb6f4f2fbb02 --- /dev/null +++ b/cmake/FindZeroMQ.cmake @@ -0,0 +1,148 @@ +################################################################################ +# Copyright (C) 2012-2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH # +# # +# This software is distributed under the terms of the # +# GNU Lesser General Public Licence (LGPL) version 3, # +# copied verbatim in the file "LICENSE" # +################################################################################ +# +# Authors: +# +# Mohammad Al-Turany +# Dario Berzano +# Dennis Klein +# Matthias Richter +# Alexey Rybalchenko +# Florian Uhlig +# +# +# ############################# +# # Locate the ZeroMQ library # +# ############################# +# +# +# Usage: +# +# find_package(ZeroMQ [version] [QUIET] [REQUIRED]) +# +# +# Defines the following variables: +# +# ZeroMQ_FOUND - Found the ZeroMQ library +# ZeroMQ_INCLUDE_DIR (CMake cache) - Include directory +# ZeroMQ_LIBRARY_SHARED (CMake cache) - Path to shared libzmq +# ZeroMQ_LIBRARY_STATIC (CMake cache) - Path to static libzmq +# ZeroMQ_VERSION - full version string +# ZeroMQ_VERSION_MAJOR - major version component +# ZeroMQ_VERSION_MINOR - minor version component +# ZeroMQ_VERSION_PATCH - patch version component +# +# +# Accepts the following variables as hints for installation directories: +# +# ZMQ_DIR (CMake var) +# AlFa_DIR (CMake var) +# SIMPATH (CMake var) +# ZEROMQ_ROOT (CMake var, ENV var) +# +# +# If the above variables are not defined, or if ZeroMQ could not be found there, +# it will look for it in the system directories. Custom ZeroMQ installations +# will always have priority over system ones. +# + +if(NOT ZeroMQ_FIND_QUIETLY) + message(STATUS "Looking for ZeroMQ") +endif() + +if(DEFINED ENV{ZEROMQ_ROOT}) + set(ZEROMQ_ROOT $ENV{ZEROMQ_ROOT}) +endif() + +find_path(ZeroMQ_INCLUDE_DIR NAMES "zmq.h" "zmq_utils.h" + HINTS "${ZMQ_DIR}/include" + "${AlFa_DIR}/include" + "${SIMPATH}/include" + "${ZEROMQ_ROOT}/include" + DOC "ZeroMQ include directories" +) + +find_library(ZeroMQ_LIBRARY_SHARED NAMES "libzmq.dylib" "libzmq.so" + HINTS "${ZMQ_DIR}/lib" + "${AlFa_DIR}/lib" + "${SIMPATH}/lib" + "${ZEROMQ_ROOT}/lib" + DOC "Path to libzmq.dylib or libzmq.so" +) + +find_library(ZeroMQ_LIBRARY_STATIC NAMES "libzmq.a" + HINTS "${ZMQ_DIR}/lib" + "${AlFa_DIR}/lib" + "${SIMPATH}/lib" + "${ZEROMQ_ROOT}/lib" + DOC "Path to libzmq.a" +) + +if(ZeroMQ_INCLUDE_DIR AND ZeroMQ_LIBRARY_SHARED AND ZeroMQ_LIBRARY_STATIC) + set(ZeroMQ_FOUND TRUE) +else() + set(ZeroMQ_FOUND FALSE) +endif() + +set(ERROR_STRING "Looking for ZeroMQ - NOT FOUND") + +if(ZeroMQ_FOUND) + find_file(ZeroMQ_HEADER_FILE "zmq.h" + ${ZeroMQ_INCLUDE_DIR} + NO_DEFAULT_PATH + ) + if (DEFINED ZeroMQ_HEADER_FILE) + file(READ "${ZeroMQ_HEADER_FILE}" _ZeroMQ_HEADER_FILE_CONTENT) + string(REGEX MATCH "#define ZMQ_VERSION_MAJOR ([0-9])" _MATCH "${_ZeroMQ_HEADER_FILE_CONTENT}") + set(ZeroMQ_VERSION_MAJOR ${CMAKE_MATCH_1}) + string(REGEX MATCH "#define ZMQ_VERSION_MINOR ([0-9])" _MATCH "${_ZeroMQ_HEADER_FILE_CONTENT}") + set(ZeroMQ_VERSION_MINOR ${CMAKE_MATCH_1}) + string(REGEX MATCH "#define ZMQ_VERSION_PATCH ([0-9])" _MATCH "${_ZeroMQ_HEADER_FILE_CONTENT}") + set(ZeroMQ_VERSION_PATCH ${CMAKE_MATCH_1}) + set(ZeroMQ_VERSION "${ZeroMQ_VERSION_MAJOR}.${ZeroMQ_VERSION_MINOR}.${ZeroMQ_VERSION_PATCH}") + if(DEFINED ZeroMQ_FIND_VERSION AND ZeroMQ_VERSION VERSION_LESS ZeroMQ_FIND_VERSION) + set(ZeroMQ_FOUND FALSE) + set(ERROR_STRING "Looking for ZeroMQ - Installed version ${ZeroMQ_VERSION} does not meet the minimum required version ${ZeroMQ_FIND_VERSION}") + endif () + unset(ZeroMQ_HEADER_FILE CACHE) + endif () + + add_library(ZeroMQ SHARED IMPORTED) + set_target_properties(ZeroMQ PROPERTIES + IMPORTED_LOCATION ${ZeroMQ_LIBRARY_SHARED} + INTERFACE_INCLUDE_DIRECTORIES ${ZeroMQ_INCLUDE_DIR} + ) +endif() + +if(ZeroMQ_FOUND) + set(ZeroMQ_LIBRARIES "${ZeroMQ_LIBRARY_STATIC};${ZeroMQ_LIBRARY_SHARED}") + if(NOT ZeroMQ_FIND_QUIETLY) + message(STATUS "Looking for ZeroMQ - Found ${ZeroMQ_INCLUDE_DIR}") + message(STATUS "Looking for ZeroMQ - Found version ${ZeroMQ_VERSION}") + endif(NOT ZeroMQ_FIND_QUIETLY) +else() + if(ZeroMQ_FIND_REQUIRED) + message(FATAL_ERROR "${ERROR_STRING}") + else() + if(NOT ZeroMQ_FIND_QUIETLY) + message(STATUS "${ERROR_STRING}") + endif(NOT ZeroMQ_FIND_QUIETLY) + endif() +endif() + +unset(ERROR_STRING) +unset(ZEROMQ_ROOT) + +mark_as_advanced( + ZeroMQ_LIBRARIES + ZeroMQ_LIBRARY_SHARED + ZeroMQ_LIBRARY_STATIC + ZeroMQ_VERSION_MAJOR + ZeroMQ_VERSION_MINOR + ZeroMQ_VERSION_PATCH +) diff --git a/cmake/QualityControlDependencies.cmake b/cmake/QualityControlDependencies.cmake index fc0b4469a28d8..b91a2f7f6a4f9 100644 --- a/cmake/QualityControlDependencies.cmake +++ b/cmake/QualityControlDependencies.cmake @@ -9,6 +9,7 @@ find_package(InfoLogger REQUIRED) find_package(DataSampling REQUIRED) find_package(ROOT 6.06.02 COMPONENTS RHTTP RMySQL Gui REQUIRED) find_package(CURL REQUIRED) +find_package(ZeroMQ REQUIRED) # todo not sure why this is needed if (BOOST_FOUND AND NOT Boost_FOUND) @@ -111,3 +112,16 @@ o2_define_bucket( ${Boost_INCLUDE_DIRS} ${Configuration_INCLUDE_DIRS} ) + + +o2_define_bucket( + NAME + o2_qc_tobject2json + + DEPENDENCIES + o2_qualitycontrol_bucket + ${ZeroMQ_LIBRARY_STATIC} + + SYSTEMINCLUDE_DIRECTORIES + ${ZeroMQ_INCLUDE_DIR} +)