Skip to content

MINIFICPP-2894 Add FetchOPCHistory processor - #2265

Open
lordgamez wants to merge 3 commits into
apache:mainfrom
lordgamez:MINIFICPP-2894
Open

lordgamez wants to merge 3 commits into
apache:mainfrom
lordgamez:MINIFICPP-2894

Conversation

@lordgamez

Copy link
Copy Markdown
Contributor
  • Additionally changed the other OPC UA processors to use ISO-8601 timestamp format in attributes

https://issues.apache.org/jira/browse/MINIFICPP-2894


Thank you for submitting a contribution to Apache NiFi - MiNiFi C++.

In order to streamline the review of the contribution we ask you to ensure the following steps have been taken:

For all changes:

  • Is there a JIRA ticket associated with this PR? Is it referenced in the commit message?

  • Does your PR title start with MINIFICPP-XXXX where XXXX is the JIRA number you are trying to resolve? Pay particular attention to the hyphen "-" character.

  • Has your PR been rebased against the latest commit within the target branch (typically main)?

  • Is your initial contribution a single, squashed commit?

For code changes:

  • If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0?
  • If applicable, have you updated the LICENSE file?
  • If applicable, have you updated the NOTICE file?

For documentation related changes:

  • Have you ensured that format looks appropriate for the output in which it is rendered?

Note:

Please ensure that once the PR is submitted, you check GitHub Actions CI results for build issues and submit an update to your PR as soon as possible.

- Additionally changed the other OPC UA processors to use ISO-8601 timestamp
  format in attributes

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

History state handling, failure rollback, batching, timestamp validation, and variant conversion contain correctness issues.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 2 High severity · 5 Medium severity

Open (7)
What changed in this PR

Adds an OPC UA historical-data processor with incremental state tracking and optional record-set output.

Changes:

  • Adds FetchOPCHistory, shared conversion/history APIs, and ISO-8601 timestamps.
  • Adds unit and integration coverage with historical OPC UA test infrastructure.
  • Updates processor documentation, manifests, and Behave helpers.
File Description
README.md Lists the new processor.
PROCESSORS.md Documents properties and outputs.
extensions/​opc/​tests/​OpcUaTestServer.h Adds historical-data test support.
extensions/​opc/​tests/​OPCCommonTests.cpp Tests variant conversion.
extensions/​opc/​tests/​FetchOPCProcessorTests.cpp Updates node-ID expectations.
extensions/​opc/​tests/​FetchOPCHistoryTests.cpp Tests history fetching and state.
extensions/​opc/​tests/​features/​steps/​steps.py Adds historical server setup.
extensions/​opc/​tests/​features/​opcua.feature Adds end-to-end scenarios.
extensions/​opc/​src/​OPCCommon.cpp Adds history reads and shared conversion.
extensions/​opc/​src/​FetchOPCHistory.cpp Implements the processor.
extensions/​opc/​include/​OPCCommon.h Exposes history-related APIs and types.
extensions/​opc/​include/​FetchOPCProcessor.h Updates timestamp documentation.
extensions/​opc/​include/​FetchOPCHistory.h Defines the processor contract.
behave_framework/​src/​minifi_behave/​steps/​flow_building_steps.py Supports per-flow controller services.
behave_framework/​src/​minifi_behave/​steps/​checking_steps.py Adds container-specific assertions.
.github/​references/​ubuntu_22_04_clang_arm_manifest.json Registers processor metadata.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +77 to +80
if (has_modification_info) {
const auto update_type = entry.modification_info ? updateTypeToString(entry.modification_info->updateType) : "";
raw = std::to_string(entry.modificationTime()) + ":" + update_type + raw;
}
Comment on lines +387 to +391
if (retval != UA_STATUSCODE_GOOD) {
logger_->log_error("Failed to read OPC UA node history, status code: {}", UA_StatusCode_name(retval));
context.yield();
return;
}
Comment on lines +302 to +305
case opc::OPCNodeIDType::Path:
readPathReferenceTypes(context, node_id_);
path_node_id_resolved_ = false;
break;
Comment on lines +311 to +312
start_timestamp_ = utils::parseOptionalProperty(context, StartTimestamp) | utils::andThen(utils::timeutils::parseRfc3339);
end_timestamp_ = utils::parseOptionalProperty(context, EndTimestamp) | utils::andThen(utils::timeutils::parseRfc3339);
Comment on lines +497 to +500
std::string variantToString(const UA_Variant& variant, BinaryEncoding binary_encoding) {
if (variant.type == nullptr || variant.data == nullptr) {
throw OPCException(GENERAL_EXCEPTION, "Cannot convert an empty variant to string");
}
Comment on lines 502 to +505
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_DATATYPEKIND_BOOLEAN: {
bool b = false;
memcpy(&b, nd.data.data(), sizeof(bool));
ret_val = b ? "True" : "False";
break;
}
case UA_DATATYPEKIND_SBYTE: {
int8_t i8t = 0;
memcpy(&i8t, nd.data.data(), sizeof(i8t));
ret_val = std::to_string(i8t);
break;
}
case UA_DATATYPEKIND_BYTE: {
uint8_t ui8t = 0;
memcpy(&ui8t, nd.data.data(), sizeof(ui8t));
ret_val = std::to_string(ui8t);
break;
}
case UA_DATATYPEKIND_INT16: {
int16_t i16t = 0;
memcpy(&i16t, nd.data.data(), sizeof(i16t));
ret_val = std::to_string(i16t);
break;
case UA_DATATYPEKIND_LOCALIZEDTEXT: {
const auto *value = static_cast<const UA_String *>(variant.data);
return {reinterpret_cast<const char *>(value->data), value->length};
Comment on lines +590 to +592
return UA_Client_HistoryRead_modified(client_, &node_id, callback, start_time, end_time, UA_STRING_NULL, false, 0, UA_TIMESTAMPSTORETURN_SOURCE, callback_context);
}
return UA_Client_HistoryRead_raw(client_, &node_id, callback, start_time, end_time, UA_STRING_NULL, false, 0, UA_TIMESTAMPSTORETURN_SOURCE, callback_context);

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants