This is an automated email from the ASF dual-hosted git repository. szaszm pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
commit f5b2ec7ff12994c39c05891fc06fbf24c5f84cba Author: Gabor Gyimesi <[email protected]> AuthorDate: Thu Oct 6 12:39:24 2022 +0200 MINIFICPP-1941 Upgrade OPC UA library to version 1.3.3 Closes #1423 Signed-off-by: Marton Szasz <[email protected]> --- cmake/BundledOpen62541.cmake | 9 +-- .../minifi/core/OPCUAServerContainer.py | 2 +- extensions/opc/include/opc.h | 11 ++-- extensions/opc/src/opc.cpp | 64 +++++++++++----------- thirdparty/open62541/open62541.patch | 49 +++++++---------- 5 files changed, 64 insertions(+), 71 deletions(-) diff --git a/cmake/BundledOpen62541.cmake b/cmake/BundledOpen62541.cmake index da1369a48..56c75ea98 100644 --- a/cmake/BundledOpen62541.cmake +++ b/cmake/BundledOpen62541.cmake @@ -34,16 +34,17 @@ function(use_bundled_open62541 SOURCE_DIR BINARY_DIR) set(OPEN62541_CMAKE_ARGS ${PASSTHROUGH_CMAKE_ARGS} "-DCMAKE_INSTALL_PREFIX=${OPEN62541_BYPRODUCT_DIR}" - -DOPEN62541_VERSION=v1.0 - -DUA_ENABLE_ENCRYPTION=ON) + -DOPEN62541_VERSION=v1.3.3 + -DUA_ENABLE_ENCRYPTION=ON + -DUA_FORCE_WERROR=OFF) append_third_party_passthrough_args(OPEN62541_CMAKE_ARGS "${OPEN62541_CMAKE_ARGS}") # Build project ExternalProject_Add( open62541-external - URL "https://github.com/open62541/open62541/archive/v1.2.2.tar.gz" - URL_HASH "SHA256=9b5bfd811ee523be601f11abc514a93c67fe5c6e957cd6c36fe6ea4f28e009bb" + URL "https://github.com/open62541/open62541/archive/v1.3.3.tar.gz" + URL_HASH "SHA256=52c049c0f107b4cc382c9e480d677a6360cdd96c472f84689af91b423bd108cb" SOURCE_DIR "${BINARY_DIR}/thirdparty/open62541-src" PATCH_COMMAND ${PC} LIST_SEPARATOR % # This is needed for passing semicolon-separated lists diff --git a/docker/test/integration/minifi/core/OPCUAServerContainer.py b/docker/test/integration/minifi/core/OPCUAServerContainer.py index 77e4e59e7..ca2cd2861 100644 --- a/docker/test/integration/minifi/core/OPCUAServerContainer.py +++ b/docker/test/integration/minifi/core/OPCUAServerContainer.py @@ -31,7 +31,7 @@ class OPCUAServerContainer(Container): logging.info('Creating and running OPC UA server docker container...') self.client.containers.run( - "lordgamez/open62541", + "lordgamez/open62541:1.3.3", detach=True, name=self.name, network=self.network.name, diff --git a/extensions/opc/include/opc.h b/extensions/opc/include/opc.h index 6c0f9872d..173b7bf04 100644 --- a/extensions/opc/include/opc.h +++ b/extensions/opc/include/opc.h @@ -24,6 +24,7 @@ #include <set> #include <vector> #include <memory> +#include <string_view> #include "open62541/client.h" #include "logging/Logger.h" @@ -55,7 +56,7 @@ class Client { ~Client(); NodeData getNodeData(const UA_ReferenceDescription *ref, const std::string& basePath = ""); UA_ReferenceDescription * getNodeReference(UA_NodeId nodeId); - void traverse(UA_NodeId nodeId, std::function<nodeFoundCallBackFunc> cb, const std::string& basePath = "", uint64_t maxDepth = 0, bool fetchRoot = true); + void traverse(UA_NodeId nodeId, const std::function<nodeFoundCallBackFunc>& cb, const std::string& basePath = "", uint64_t maxDepth = 0, bool fetchRoot = true); bool exists(UA_NodeId nodeId); UA_StatusCode translateBrowsePathsToNodeIdsRequest(const std::string& path, std::vector<UA_NodeId>& foundNodeIDs, const std::shared_ptr<core::logging::Logger>& logger); @@ -63,14 +64,14 @@ class Client { UA_StatusCode update_node(const UA_NodeId nodeId, T value); template<typename T> - UA_StatusCode add_node(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, T value, UA_NodeId *receivedNodeId); + UA_StatusCode add_node(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, T value, UA_NodeId *receivedNodeId); - static std::unique_ptr<Client> createClient(std::shared_ptr<core::logging::Logger> logger, const std::string& applicationURI, + static std::unique_ptr<Client> createClient(const std::shared_ptr<core::logging::Logger>& logger, const std::string& applicationURI, const std::vector<char>& certBuffer, const std::vector<char>& keyBuffer, const std::vector<std::vector<char>>& trustBuffers); private: - Client(std::shared_ptr<core::logging::Logger> logger, const std::string& applicationURI, + Client(const std::shared_ptr<core::logging::Logger>& logger, const std::string& applicationURI, const std::vector<char>& certBuffer, const std::vector<char>& keyBuffer, const std::vector<std::vector<char>>& trustBuffers); @@ -82,7 +83,7 @@ using ClientPtr = std::unique_ptr<Client>; struct NodeData { std::vector<uint8_t> data; - uint16_t dataTypeID; + UA_DataTypeKind dataTypeID; std::map<std::string, std::string> attributes; virtual ~NodeData() { diff --git a/extensions/opc/src/opc.cpp b/extensions/opc/src/opc.cpp index 71d9f9482..c10bb4766 100644 --- a/extensions/opc/src/opc.cpp +++ b/extensions/opc/src/opc.cpp @@ -108,7 +108,7 @@ core::logging::LOG_LEVEL MapOPCLogLevel(UA_LogLevel ualvl) { * End of internal functions */ -Client::Client(std::shared_ptr<core::logging::Logger> logger, const std::string& applicationURI, +Client::Client(const std::shared_ptr<core::logging::Logger>& logger, const std::string& applicationURI, const std::vector<char>& certBuffer, const std::vector<char>& keyBuffer, const std::vector<std::vector<char>>& trustBuffers) { client_ = UA_Client_new(); @@ -221,7 +221,7 @@ NodeData Client::getNodeData(const UA_ReferenceDescription *ref, const std::stri } nodedata.attributes["Browsename"] = browsename; nodedata.attributes["Full path"] = basePath + "/" + browsename; - nodedata.dataTypeID = UA_TYPES_COUNT; + nodedata.dataTypeID = static_cast<UA_DataTypeKind>(UA_DATATYPEKINDS); UA_Variant* var = UA_Variant_new(); if (UA_Client_readValueAttribute(client_, ref->nodeId.nodeId, var) == UA_STATUSCODE_GOOD && var->type != nullptr && var->data != nullptr) { // Because the timestamps are eliminated in readValueAttribute for simplification @@ -243,7 +243,7 @@ NodeData Client::getNodeData(const UA_ReferenceDescription *ref, const std::stri nodedata.attributes["Sourcetimestamp"] = source_timestamp; UA_ReadResponse_clear(&response); - nodedata.dataTypeID = var->type->typeIndex; + nodedata.dataTypeID = static_cast<UA_DataTypeKind>(var->type->typeKind); nodedata.addVariant(var); if (var->type->typeName) { nodedata.attributes["Typename"] = std::string(var->type->typeName); @@ -276,7 +276,7 @@ UA_ReferenceDescription * Client::getNodeReference(UA_NodeId nodeId) { return ref; } -void Client::traverse(UA_NodeId nodeId, std::function<nodeFoundCallBackFunc> cb, const std::string& basePath, uint64_t maxDepth, bool fetchRoot) { +void Client::traverse(UA_NodeId nodeId, const std::function<nodeFoundCallBackFunc>& cb, const std::string& basePath, uint64_t maxDepth, bool fetchRoot) { if (fetchRoot) { UA_ReferenceDescription *rootRef = getNodeReference(nodeId); if ((rootRef->nodeClass == UA_NODECLASS_VARIABLE || rootRef->nodeClass == UA_NODECLASS_OBJECT) && rootRef->browseName.name.length > 0) { @@ -397,16 +397,16 @@ UA_StatusCode Client::translateBrowsePathsToNodeIdsRequest(const std::string& pa } template<typename T> -UA_StatusCode Client::add_node(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, T value, UA_NodeId *receivedNodeId) { +UA_StatusCode Client::add_node(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, T value, UA_NodeId *receivedNodeId) { UA_VariableAttributes attr = UA_VariableAttributes_default; add_value_to_variant(&attr.value, value); char local[6] = "en-US"; - attr.displayName = UA_LOCALIZEDTEXT(local, const_cast<char*>(browseName.c_str())); + attr.displayName = UA_LOCALIZEDTEXT(local, const_cast<char*>(browseName.data())); UA_StatusCode sc = UA_Client_addVariableNode(client_, targetNodeId, parentNodeId, UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES), - UA_QUALIFIEDNAME(1, const_cast<char*>(browseName.c_str())), + UA_QUALIFIEDNAME(1, const_cast<char*>(browseName.data())), UA_NODEID_NULL, attr, receivedNodeId); UA_Variant_clear(&attr.value); @@ -422,7 +422,7 @@ UA_StatusCode Client::update_node(const UA_NodeId nodeId, T value) { return sc; } -std::unique_ptr<Client> Client::createClient(std::shared_ptr<core::logging::Logger> logger, const std::string& applicationURI, +std::unique_ptr<Client> Client::createClient(const std::shared_ptr<core::logging::Logger>& logger, const std::string& applicationURI, const std::vector<char>& certBuffer, const std::vector<char>& keyBuffer, const std::vector<std::vector<char>>& trustBuffers) { try { @@ -443,16 +443,16 @@ template UA_StatusCode Client::update_node<bool>(const UA_NodeId nodeId, bool va template UA_StatusCode Client::update_node<const char *>(const UA_NodeId nodeId, const char * value); template UA_StatusCode Client::update_node<std::string>(const UA_NodeId nodeId, std::string value); -template UA_StatusCode Client::add_node<int64_t>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, int64_t value, UA_NodeId *receivedNodeId); -template UA_StatusCode Client::add_node<uint64_t>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, uint64_t value, UA_NodeId *receivedNodeId); -template UA_StatusCode Client::add_node<int32_t>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, int32_t value, UA_NodeId *receivedNodeId); -template UA_StatusCode Client::add_node<uint32_t>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, uint32_t value, UA_NodeId *receivedNodeId); -template UA_StatusCode Client::add_node<float>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, float value, UA_NodeId *receivedNodeId); -template UA_StatusCode Client::add_node<double>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, double value, UA_NodeId *receivedNodeId); -template UA_StatusCode Client::add_node<bool>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, bool value, UA_NodeId *receivedNodeId); -template UA_StatusCode Client::add_node<const char *>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, +template UA_StatusCode Client::add_node<int64_t>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, int64_t value, UA_NodeId *receivedNodeId); +template UA_StatusCode Client::add_node<uint64_t>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, uint64_t value, UA_NodeId *receivedNodeId); +template UA_StatusCode Client::add_node<int32_t>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, int32_t value, UA_NodeId *receivedNodeId); +template UA_StatusCode Client::add_node<uint32_t>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, uint32_t value, UA_NodeId *receivedNodeId); +template UA_StatusCode Client::add_node<float>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, float value, UA_NodeId *receivedNodeId); +template UA_StatusCode Client::add_node<double>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, double value, UA_NodeId *receivedNodeId); +template UA_StatusCode Client::add_node<bool>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, bool value, UA_NodeId *receivedNodeId); +template UA_StatusCode Client::add_node<const char *>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, const char * value, UA_NodeId *receivedNodeId); -template UA_StatusCode Client::add_node<std::string>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string browseName, +template UA_StatusCode Client::add_node<std::string>(const UA_NodeId parentNodeId, const UA_NodeId targetNodeId, std::string_view browseName, std::string value, UA_NodeId *receivedNodeId); std::set<std::string> stringToOPCDataTypeMapKeys() { @@ -466,59 +466,59 @@ std::set<std::string> stringToOPCDataTypeMapKeys() { std::string nodeValue2String(const NodeData& nd) { std::string ret_val; switch (nd.dataTypeID) { - case UA_TYPES_STRING: - case UA_TYPES_LOCALIZEDTEXT: - case UA_TYPES_BYTESTRING: { + case UA_DATATYPEKIND_STRING: + case UA_DATATYPEKIND_LOCALIZEDTEXT: + case UA_DATATYPEKIND_BYTESTRING: { UA_String value = *reinterpret_cast<UA_String *>(nd.var_->data); ret_val = std::string(reinterpret_cast<const char *>(value.data), value.length); break; } - case UA_TYPES_BOOLEAN: + case UA_DATATYPEKIND_BOOLEAN: bool b; memcpy(&b, nd.data.data(), sizeof(bool)); ret_val = b ? "True" : "False"; break; - case UA_TYPES_SBYTE: + case UA_DATATYPEKIND_SBYTE: int8_t i8t; memcpy(&i8t, nd.data.data(), sizeof(i8t)); ret_val = std::to_string(i8t); break; - case UA_TYPES_BYTE: + case UA_DATATYPEKIND_BYTE: uint8_t ui8t; memcpy(&ui8t, nd.data.data(), sizeof(ui8t)); ret_val = std::to_string(ui8t); break; - case UA_TYPES_INT16: + case UA_DATATYPEKIND_INT16: int16_t i16t; memcpy(&i16t, nd.data.data(), sizeof(i16t)); ret_val = std::to_string(i16t); break; - case UA_TYPES_UINT16: + case UA_DATATYPEKIND_UINT16: uint16_t ui16t; memcpy(&ui16t, nd.data.data(), sizeof(ui16t)); ret_val = std::to_string(ui16t); break; - case UA_TYPES_INT32: + case UA_DATATYPEKIND_INT32: int32_t i32t; memcpy(&i32t, nd.data.data(), sizeof(i32t)); ret_val = std::to_string(i32t); break; - case UA_TYPES_UINT32: + case UA_DATATYPEKIND_UINT32: uint32_t ui32t; memcpy(&ui32t, nd.data.data(), sizeof(ui32t)); ret_val = std::to_string(ui32t); break; - case UA_TYPES_INT64: + case UA_DATATYPEKIND_INT64: int64_t i64t; memcpy(&i64t, nd.data.data(), sizeof(i64t)); ret_val = std::to_string(i64t); break; - case UA_TYPES_UINT64: + case UA_DATATYPEKIND_UINT64: uint64_t ui64t; memcpy(&ui64t, nd.data.data(), sizeof(ui64t)); ret_val = std::to_string(ui64t); break; - case UA_TYPES_FLOAT: + case UA_DATATYPEKIND_FLOAT: if (sizeof(float) == 4 && std::numeric_limits<float>::is_iec559) { float f; memcpy(&f, nd.data.data(), sizeof(float)); @@ -527,7 +527,7 @@ std::string nodeValue2String(const NodeData& nd) { throw OPCException(GENERAL_EXCEPTION, "Float is non-standard on this system, OPC data cannot be extracted!"); } break; - case UA_TYPES_DOUBLE: + case UA_DATATYPEKIND_DOUBLE: if (sizeof(double) == 8 && std::numeric_limits<double>::is_iec559) { double d; memcpy(&d, nd.data.data(), sizeof(double)); @@ -536,7 +536,7 @@ std::string nodeValue2String(const NodeData& nd) { throw OPCException(GENERAL_EXCEPTION, "Double is non-standard on this system, OPC data cannot be extracted!"); } break; - case UA_TYPES_DATETIME: { + case UA_DATATYPEKIND_DATETIME: { UA_DateTime dt; memcpy(&dt, nd.data.data(), sizeof(UA_DateTime)); ret_val = opc::OPCDateTime2String(dt); diff --git a/thirdparty/open62541/open62541.patch b/thirdparty/open62541/open62541.patch index 17a5ab172..3ad611fe0 100644 --- a/thirdparty/open62541/open62541.patch +++ b/thirdparty/open62541/open62541.patch @@ -1,27 +1,18 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt -index 9184b943..44ae77cf 100644 +index 1934374e..4babdd20 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt -@@ -7,7 +7,7 @@ endif() - +@@ -11,7 +11,7 @@ endif() + string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE_LOWER_CASE) - + -set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake") +list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/tools/cmake") - find_package(PythonInterp REQUIRED) + find_package(Python3 REQUIRED) + set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE}) find_package(Git) - include(AssignSourceGroup) -@@ -526,7 +526,7 @@ if(NOT UA_FORCE_CPP AND (CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID}" ST - check_add_cc_flag("-Wall") # Warnings - check_add_cc_flag("-Wextra") # More warnings - check_add_cc_flag("-Wpedantic") # Standard compliance -- check_add_cc_flag("-Werror") # All warnings are errors -+ # check_add_cc_flag("-Werror") # All warnings are errors - - check_add_cc_flag("-Wno-static-in-inline") # Clang doesn't like the use of static inline methods inside static inline methods - check_add_cc_flag("-Wno-overlength-strings") # May happen in the nodeset compiler when complex values are directly encoded -@@ -576,17 +576,17 @@ if(NOT UA_FORCE_CPP AND (CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID}" ST - +@@ -721,17 +721,17 @@ if(NOT UA_FORCE_CPP AND (CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID}" ST + # IPO requires too much memory for unit tests # GCC docu recommends to compile all files with the same options, therefore ignore it completely - if(NOT UA_BUILD_UNIT_TESTS AND NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION) @@ -35,17 +26,17 @@ index 9184b943..44ae77cf 100644 - endif() - endif() - endif() -+ # if(NOT UA_BUILD_UNIT_TESTS AND NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION) -+ # # needed to check if IPO is supported (check needs cmake > 3.9) -+ # if("${CMAKE_VERSION}" VERSION_GREATER 3.9) -+ # cmake_policy(SET CMP0069 NEW) # needed as long as required cmake < 3.9 -+ # include(CheckIPOSupported) -+ # check_ipo_supported(RESULT CC_HAS_IPO) # Inter Procedural Optimization / Link Time Optimization (should be same as -flto) -+ # if(CC_HAS_IPO) -+ # set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) -+ # endif() -+ # endif() -+ # endif() ++ # if(NOT UA_BUILD_UNIT_TESTS AND NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION) ++ # # needed to check if IPO is supported (check needs cmake > 3.9) ++ # if("${CMAKE_VERSION}" VERSION_GREATER 3.9) ++ # cmake_policy(SET CMP0069 NEW) # needed as long as required cmake < 3.9 ++ # include(CheckIPOSupported) ++ # check_ipo_supported(RESULT CC_HAS_IPO) # Inter Procedural Optimization / Link Time Optimization (should be same as -flto) ++ # if(CC_HAS_IPO) ++ # set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) ++ # endif() ++ # endif() ++ # endif() endif() - + if(UA_ENABLE_AMALGAMATION)
