Skip to content

Commit 414550a

Browse files
committed
Merge branch 'tg-35-implement-reporters' into 'main'
WIF - Reporters See merge request feta/wif-group/libwif!35
2 parents b52e0f5 + bdcb3a4 commit 414550a

File tree

6 files changed

+264
-5
lines changed

6 files changed

+264
-5
lines changed

cmake/dependencies.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ find_package(Python3 REQUIRED COMPONENTS Development NumPy)
44

55
if(BUILD_WITH_UNIREC)
66
find_package(UNIREC 3.0.0 REQUIRED)
7+
find_package(UNIREC++ 3.2.0 REQUIRED)
78
endif()
89

910
# Set define for none depricated API for NUMPY

cmake/modules/FindUNIREC++.cmake

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Find the Unirec++ includes and library
2+
#
3+
# This module defines the following IMPORTED targets:
4+
#
5+
# unirec::unirec++ - The "unirec++" library, if found.
6+
#
7+
# This module will set the following variables in your project:
8+
#
9+
# UNIREC++_INCLUDE_DIRS - where to find <unirec++/unirec++.hpp>, etc.
10+
# UNIREC++_LIBRARIES - List of libraries when using unirec++.
11+
# UNIREC++_FOUND - True if the unirec++ library has been found.
12+
13+
# Use pkg-config (if available) to get the library directories and then use
14+
# these values as hints for find_path() and find_library() functions.
15+
find_package(PkgConfig QUIET)
16+
if (PKG_CONFIG_FOUND)
17+
pkg_check_modules(PC_UNIREC++ QUIET unirec++)
18+
endif()
19+
20+
find_path(
21+
UNIREC++_INCLUDE_DIR unirec++
22+
HINTS ${PC_UNIREC++_INCLUDEDIR} ${PC_UNIREC++_INCLUDE_DIRS}
23+
PATH_SUFFIXES include
24+
)
25+
26+
find_library(
27+
UNIREC++_LIBRARY NAMES unirec++
28+
HINTS ${PC_UNIREC++_LIBDIR} ${PC_UNIREC++_LIBRARY_DIRS}
29+
PATH_SUFFIXES lib lib64
30+
)
31+
32+
if (PC_UNIREC++_VERSION)
33+
# Version extracted from pkg-config
34+
set(UNIREC++_VERSION_STRING ${PC_UNIREC++_VERSION})
35+
endif()
36+
37+
# Handle find_package() arguments (i.e. QUIETLY and REQUIRED) and set
38+
# UNIREC++_FOUND to TRUE if all listed variables are filled.
39+
include(FindPackageHandleStandardArgs)
40+
find_package_handle_standard_args(
41+
UNIREC++
42+
REQUIRED_VARS UNIREC++_LIBRARY UNIREC++_INCLUDE_DIR
43+
VERSION_VAR UNIREC++_VERSION_STRING
44+
)
45+
46+
set(UNIREC++_INCLUDE_DIRS ${UNIREC++_INCLUDE_DIR})
47+
set(UNIREC++_LIBRARIES ${UNIREC++_LIBRARY})
48+
mark_as_advanced(UNIREC++_INCLUDE_DIR UNIREC++_LIBRARY)
49+
50+
if (UNIREC++_FOUND)
51+
# Create imported library with all dependencies
52+
if (NOT TARGET unirec::unirec++ AND EXISTS "${UNIREC++_LIBRARIES}")
53+
add_library(unirec::unirec++ UNKNOWN IMPORTED)
54+
set_target_properties(unirec::unirec++ PROPERTIES
55+
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
56+
IMPORTED_LOCATION "${UNIREC++_LIBRARIES}"
57+
INTERFACE_INCLUDE_DIRECTORIES "${UNIREC++_INCLUDE_DIRS}")
58+
endif()
59+
endif()

include/wif/reporters/reporter.hpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* @file
3+
* @author Richard Plny <[email protected]>
4+
* @brief Reporter
5+
*
6+
* SPDX-License-Identifier: BSD-3-Clause
7+
*/
8+
9+
#pragma once
10+
11+
#include "wif/storage/dataVariant.hpp"
12+
13+
#include <vector>
14+
15+
namespace WIF {
16+
17+
/**
18+
* @brief Reporter class
19+
*
20+
* Represents an abstract model for reporting (exporting) data and information
21+
*/
22+
class Reporter {
23+
public:
24+
/**
25+
* @brief Destroy the Reporter object
26+
*
27+
*/
28+
virtual ~Reporter() = default;
29+
30+
/**
31+
* @brief Method, which instructs the reporter to start a new record
32+
* All data received by report(...) methods will be stored to the current record
33+
*
34+
*/
35+
virtual void onRecordStart() = 0;
36+
37+
/**
38+
* @brief Method to report data to the reporter
39+
* @param data
40+
*/
41+
virtual void report(const DataVariant& data) = 0;
42+
43+
/**
44+
* @brief Method, which tells the reporter to prepare current record for send and then send it
45+
* Record can be also stored in queue / bulk for sending out (rather than sending it out at the
46+
* moment). If the record needs to be exported right away, use flush()
47+
*
48+
*/
49+
virtual void onRecordEnd() = 0;
50+
51+
/**
52+
* @brief Forces reporter to send right now all records in queue / bulk (if used)
53+
* If reporter does not use queue or bulk and sends each record during onRecordEnd(), this
54+
* method does nothing
55+
*/
56+
virtual void flush() = 0;
57+
};
58+
59+
} // namespace WIF
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/**
2+
* @file
3+
* @author Richard Plny <[email protected]>
4+
* @brief Unirec reporter interface
5+
*
6+
* SPDX-License-Identifier: BSD-3-Clause
7+
*/
8+
9+
#pragma once
10+
11+
#include "wif/reporters/reporter.hpp"
12+
13+
#include <unirec++/unirec.hpp>
14+
15+
namespace WIF {
16+
17+
/**
18+
* @brief Unirec Reporter class
19+
*
20+
* Reporter specialization which sends data in UniRec format to Trap interface
21+
*/
22+
class UnirecReporter : public Reporter {
23+
public:
24+
/**
25+
* @brief Construct a new Unirec Reporter object
26+
*
27+
* @param outputInterface output interface where data will be sent
28+
*/
29+
UnirecReporter(Nemea::UnirecOutputInterface& outputInterface);
30+
31+
/**
32+
* @brief Update UniRec field IDs
33+
* Should be called after UniRec template was changed
34+
*
35+
* @param unirecFieldIDs
36+
*/
37+
void updateUnirecFieldIDs(const std::vector<ur_field_id_t>& unirecFieldIDs);
38+
39+
/*! @copydoc Reporter::onRecordStart()
40+
*/
41+
virtual void onRecordStart() override;
42+
43+
/*! @copydoc Reporter::report(const DataVariant& data)
44+
* Data is stored to the UniRec record to the next ID
45+
*/
46+
void report(const DataVariant& data) override;
47+
48+
/*! @copydoc Reporter::onRecordEnd()
49+
* Current Unirec Record is sent to Unirec Output Interface
50+
*/
51+
virtual void onRecordEnd() override;
52+
53+
/*! @copydoc Reporter::flush()
54+
* Internally calls Nemea::UnirecOutputInterface::sendFlush()
55+
*/
56+
virtual void flush() override;
57+
58+
private:
59+
unsigned m_currentUnirecID = 0;
60+
std::vector<ur_field_id_t> m_unirecFieldIDs;
61+
Nemea::UnirecOutputInterface& m_outputInterface;
62+
};
63+
64+
} // namespace WIF

src/wif/CMakeLists.txt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,23 @@ set(LIBWIF_SOURCES
1212
storage/ipAddress.cpp
1313
)
1414

15-
if(BUILD_WITH_UNIREC)
16-
list(APPEND LIBWIF_SOURCES
17-
)
18-
endif()
19-
2015
set(LIBWIF_LIBS
2116
Boost::regex
2217
Python3::Python
2318
Python3::NumPy
2419
dstlib::dst
2520
)
2621

22+
if(BUILD_WITH_UNIREC)
23+
list(APPEND LIBWIF_SOURCES
24+
reporters/unirecReporter.cpp
25+
)
26+
list(APPEND LIBWIF_LIBS
27+
unirec::unirec
28+
unirec::unirec++
29+
)
30+
endif()
31+
2732
add_library(wif SHARED ${LIBWIF_SOURCES})
2833
target_link_libraries(wif PRIVATE ${LIBWIF_LIBS})
2934
target_include_directories(wif PUBLIC ${CMAKE_SOURCE_DIR}/include)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/**
2+
* @file
3+
* @author Richard Plny <[email protected]>
4+
* @brief Unirec reporter implementation
5+
*
6+
* SPDX-License-Identifier: BSD-3-Clause
7+
*/
8+
9+
#include "wif/reporters/unirecReporter.hpp"
10+
11+
namespace WIF {
12+
13+
UnirecReporter::UnirecReporter(Nemea::UnirecOutputInterface& outputInterface)
14+
: m_outputInterface(outputInterface)
15+
{
16+
}
17+
18+
void UnirecReporter::updateUnirecFieldIDs(const std::vector<ur_field_id_t>& unirecFieldIDs)
19+
{
20+
m_unirecFieldIDs = unirecFieldIDs;
21+
}
22+
23+
void UnirecReporter::onRecordStart()
24+
{
25+
m_currentUnirecID = 0;
26+
}
27+
28+
void UnirecReporter::report(const DataVariant& data)
29+
{
30+
ur_field_id_t fieldID = m_unirecFieldIDs[m_currentUnirecID++];
31+
auto& record = m_outputInterface.getUnirecRecord();
32+
33+
if (std::holds_alternative<uint8_t>(data)) {
34+
auto value = std::get<uint8_t>(data);
35+
record.setFieldFromType<uint8_t>(value, fieldID);
36+
} else if (std::holds_alternative<uint16_t>(data)) {
37+
auto value = std::get<uint16_t>(data);
38+
record.setFieldFromType<uint16_t>(value, fieldID);
39+
} else if (std::holds_alternative<uint32_t>(data)) {
40+
auto value = std::get<uint32_t>(data);
41+
record.setFieldFromType<uint32_t>(value, fieldID);
42+
} else if (std::holds_alternative<uint64_t>(data)) {
43+
auto value = std::get<uint64_t>(data);
44+
record.setFieldFromType<uint64_t>(value, fieldID);
45+
} else if (std::holds_alternative<double>(data)) {
46+
auto value = std::get<double>(data);
47+
record.setFieldFromType<double>(value, fieldID);
48+
} else if (std::holds_alternative<std::string>(data)) {
49+
auto value = std::get<std::string>(data);
50+
record.setFieldFromType<std::string>(value, fieldID);
51+
} else if (std::holds_alternative<IpAddress>(data)) {
52+
auto value = std::get<IpAddress>(data);
53+
Nemea::IpAddress nemeaIp(value.toString());
54+
record.setFieldFromType<Nemea::IpAddress>(nemeaIp, fieldID);
55+
} else if (std::holds_alternative<std::vector<double>>(data)) {
56+
auto value = std::get<std::vector<double>>(data);
57+
record.setFieldFromVector<double>(value, fieldID);
58+
}
59+
}
60+
61+
void UnirecReporter::onRecordEnd()
62+
{
63+
m_outputInterface.send(m_outputInterface.getUnirecRecord());
64+
}
65+
66+
void UnirecReporter::flush()
67+
{
68+
m_outputInterface.sendFlush();
69+
}
70+
71+
} // namespace WIF

0 commit comments

Comments
 (0)