diff --git a/.github/references/ubuntu_22_04_clang_arm_manifest.json b/.github/references/ubuntu_22_04_clang_arm_manifest.json
index 53f33f8070..779105a480 100644
--- a/.github/references/ubuntu_22_04_clang_arm_manifest.json
+++ b/.github/references/ubuntu_22_04_clang_arm_manifest.json
@@ -6570,7 +6570,7 @@
"Namespace index": {
"name": "Namespace index",
"description": "The index of the namespace.",
- "validator": "INTEGER_VALIDATOR",
+ "validator": "NON_NEGATIVE_INTEGER_VALIDATOR",
"required": "true",
"sensitive": "false",
"expressionLanguageScope": "NONE",
@@ -6746,7 +6746,7 @@
"Namespace index": {
"name": "Namespace index",
"description": "The index of the namespace.",
- "validator": "INTEGER_VALIDATOR",
+ "validator": "NON_NEGATIVE_INTEGER_VALIDATOR",
"required": "true",
"sensitive": "false",
"expressionLanguageScope": "NONE",
@@ -6779,6 +6779,10 @@
{
"value": "String",
"displayName": "String"
+ },
+ {
+ "value": "Guid",
+ "displayName": "Guid"
}
]
},
@@ -6903,17 +6907,17 @@
},
"Parent node ID": {
"name": "Parent node ID",
- "description": "Specifies the ID of the root node to traverse",
+ "description": "Specifies the ID of the root node to traverse. Only required when a new node is created.",
"validator": "VALID",
- "required": "true",
+ "required": "false",
"sensitive": "false",
"expressionLanguageScope": "NONE"
},
"Parent node ID type": {
"name": "Parent node ID type",
- "description": "Specifies the type of the provided node ID",
+ "description": "Specifies the type of the provided node ID. Only required when a new node is created.",
"validator": "VALID",
- "required": "true",
+ "required": "false",
"sensitive": "false",
"expressionLanguageScope": "NONE",
"allowableValues": [
@@ -6928,14 +6932,18 @@
{
"value": "String",
"displayName": "String"
+ },
+ {
+ "value": "Guid",
+ "displayName": "Guid"
}
]
},
"Parent node namespace index": {
"name": "Parent node namespace index",
- "description": "The index of the namespace of the parent node.",
- "validator": "INTEGER_VALIDATOR",
- "required": "true",
+ "description": "The index of the namespace of the parent node. Only used when a new node is created.",
+ "validator": "NON_NEGATIVE_INTEGER_VALIDATOR",
+ "required": "false",
"sensitive": "false",
"expressionLanguageScope": "NONE",
"defaultValue": "0"
@@ -6966,7 +6974,7 @@
},
"Target node ID type": {
"name": "Target node ID type",
- "description": "ID type of target node. Allowed values are: Int, String.",
+ "description": "ID type of target node. Allowed values are: Int, String, Guid.",
"validator": "VALID",
"required": "true",
"sensitive": "false",
diff --git a/PROCESSORS.md b/PROCESSORS.md
index 87d3c7aff5..924a08446f 100644
--- a/PROCESSORS.md
+++ b/PROCESSORS.md
@@ -945,21 +945,21 @@ Fetches OPC-UA node
In the list below, the names of required properties appear in bold. Any other properties (not in bold) are considered optional. The table also indicates any default values, and whether a property supports the NiFi Expression Language.
-| Name | Default Value | Allowable Values | Description |
-|---------------------------------|---------------|--------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| **OPC server endpoint** | | | Specifies the address, port and relative path of an OPC endpoint |
-| Application URI | | | Application URI of the client in the format 'urn:unconfigured:application'. Mandatory, if using Secure Channel and must match the URI included in the certificate's Subject Alternative Names. |
-| Username | | | Username to log in with. |
-| Password | | | Password to log in with.
**Sensitive Property: true** |
-| Certificate path | | | Path to the DER-encoded cert file |
-| Key path | | | Path to the DER-encoded key file |
-| Trusted server certificate path | | | Comma separated list of paths to the DER-encoded trusted server certificates |
-| Path reference types | | | Specify the reference types between nodes in the path if Path Node ID type is used. If not provided, all reference types are assumed to be Organizes. The format is 'referenceType1/referenceType2/.../referenceTypeN' and the supported reference types are Organizes, HasComponent, HasProperty, and HasSubtype. |
-| **Node ID type** | | Path
Int
String | Specifies the type of the provided node ID |
-| **Node ID** | | | Specifies the ID of the root node to traverse. In case of a Path Node ID Type, the path should be provided in the format of 'path/to/node'. |
-| **Namespace index** | 0 | | The index of the namespace. |
-| **Max depth** | 0 | | Specifiec the max depth of browsing. 0 means unlimited. |
-| **Lazy mode** | Off | On
New Value
Off | Only creates flowfiles from nodes with new timestamp from the server. If set to 'New Value', it will only create flowfiles if the value of the node data has changed since the last fetch, the timestamp is ignored. |
+| Name | Default Value | Allowable Values | Description |
+|---------------------------------|---------------|----------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| **OPC server endpoint** | | | Specifies the address, port and relative path of an OPC endpoint |
+| Application URI | | | Application URI of the client in the format 'urn:unconfigured:application'. Mandatory, if using Secure Channel and must match the URI included in the certificate's Subject Alternative Names. |
+| Username | | | Username to log in with. |
+| Password | | | Password to log in with.
**Sensitive Property: true** |
+| Certificate path | | | Path to the DER-encoded cert file |
+| Key path | | | Path to the DER-encoded key file |
+| Trusted server certificate path | | | Comma separated list of paths to the DER-encoded trusted server certificates |
+| Path reference types | | | Specify the reference types between nodes in the path if Path Node ID type is used. If not provided, all reference types are assumed to be Organizes. The format is 'referenceType1/referenceType2/.../referenceTypeN' and the supported reference types are Organizes, HasComponent, HasProperty, and HasSubtype. |
+| **Node ID type** | | Path
Int
String
Guid | Specifies the type of the provided node ID |
+| **Node ID** | | | Specifies the ID of the root node to traverse. In case of a Path Node ID Type, the path should be provided in the format of 'path/to/node'. |
+| **Namespace index** | 0 | | The index of the namespace. |
+| **Max depth** | 0 | | Specifiec the max depth of browsing. 0 means unlimited. |
+| **Lazy mode** | Off | On
New Value
Off | Only creates flowfiles from nodes with new timestamp from the server. If set to 'New Value', it will only create flowfiles if the value of the node data has changed since the last fetch, the timestamp is ignored. |
### Relationships
@@ -973,6 +973,7 @@ In the list below, the names of required properties appear in bold. Any other pr
| Attribute | Relationship | Description |
|-----------------|--------------|-----------------------------------------------------------------------------------------|
| NodeID | success | ID of the node. |
+| Namespace index | success | Namespace index of the node. |
| NodeID type | success | Type of the node ID. |
| Browsename | success | The browse name of the node. |
| Full path | success | The full path of the node. |
@@ -2514,11 +2515,11 @@ In the list below, the names of required properties appear in bold. Any other pr
| Key path | | | Path to the DER-encoded key file |
| Trusted server certificate path | | | Comma separated list of paths to the DER-encoded trusted server certificates |
| Path reference types | | | Specify the reference types between nodes in the path if Path Node ID type is used. If not provided, all reference types are assumed to be Organizes. The format is 'referenceType1/referenceType2/.../referenceTypeN' and the supported reference types are Organizes, HasComponent, HasProperty, and HasSubtype. |
-| **Parent node ID type** | | Path
Int
String | Specifies the type of the provided node ID |
-| **Parent node ID** | | | Specifies the ID of the root node to traverse |
-| **Parent node namespace index** | 0 | | The index of the namespace of the parent node. |
+| Parent node ID type | | Path
Int
String
Guid | Specifies the type of the provided node ID. Only required when a new node is created. |
+| Parent node ID | | | Specifies the ID of the root node to traverse. Only required when a new node is created. |
+| Parent node namespace index | 0 | | The index of the namespace of the parent node. Only used when a new node is created. |
| **Value type** | | Int64
UInt64
Int32
UInt32
Boolean
Float
Double
String | Set the OPC value type of the created nodes |
-| **Target node ID type** | | Int
String | ID type of target node. Allowed values are: Int, String.
**Supports Expression Language: true** |
+| **Target node ID type** | | | ID type of target node. Allowed values are: Int, String, Guid.
**Supports Expression Language: true** |
| **Target node ID** | | | ID of target node.
**Supports Expression Language: true** |
| Target node browse name | | | Browse name of target node. Only used when new node is created.
**Supports Expression Language: true** |
| **Target node namespace index** | 0 | | The index of the namespace of the target node.
**Supports Expression Language: true** |
diff --git a/extensions/opc/include/BaseOPCProcessor.h b/extensions/opc/include/BaseOPCProcessor.h
index 9ec4afe00c..00fd4dd565 100644
--- a/extensions/opc/include/BaseOPCProcessor.h
+++ b/extensions/opc/include/BaseOPCProcessor.h
@@ -80,10 +80,12 @@ class BaseOPCProcessor : public core::ProcessorImpl {
protected:
virtual bool reconnect();
void readPathReferenceTypes(core::ProcessContext& context, const std::string& node_id);
- void parseIdType(core::ProcessContext& context, const core::PropertyReference& prop);
+ void parseNode(core::ProcessContext& context);
std::string node_id_;
- int32_t namespace_idx_ = 0;
+ UA_UInt16 namespace_idx_ = 0;
+ bool path_node_id_resolved_ = false;
+ opc::NodeId node_;
opc::OPCNodeIDType id_type_{};
opc::ClientPtr connection_;
diff --git a/extensions/opc/include/FetchOPCHistory.h b/extensions/opc/include/FetchOPCHistory.h
index c15b636936..9e00b68f1b 100644
--- a/extensions/opc/include/FetchOPCHistory.h
+++ b/extensions/opc/include/FetchOPCHistory.h
@@ -80,7 +80,7 @@ class FetchOPCHistory final : public BaseOPCProcessor {
EXTENSIONAPI static constexpr auto NameSpaceIndex =
core::PropertyDefinitionBuilder<>::createProperty("Namespace index")
.withDescription("The index of the namespace.")
- .withValidator(core::StandardPropertyValidators::INTEGER_VALIDATOR)
+ .withValidator(core::StandardPropertyValidators::UNSIGNED_INTEGER_VALIDATOR)
.withDefaultValue("0")
.isRequired(true)
.build();
@@ -151,8 +151,6 @@ class FetchOPCHistory final : public BaseOPCProcessor {
std::optional end_timestamp_;
uint64_t batch_size_ = 0;
std::shared_ptr record_set_writer_;
- opc::NodeId node_;
- bool path_node_id_resolved_ = false;
};
} // namespace org::apache::nifi::minifi::processors
diff --git a/extensions/opc/include/FetchOPCProcessor.h b/extensions/opc/include/FetchOPCProcessor.h
index 5ae0d0ba96..8c11ae0ab7 100644
--- a/extensions/opc/include/FetchOPCProcessor.h
+++ b/extensions/opc/include/FetchOPCProcessor.h
@@ -73,10 +73,10 @@ class FetchOPCProcessor final : public BaseOPCProcessor {
EXTENSIONAPI static constexpr const char* Description = "Fetches OPC-UA node";
- EXTENSIONAPI static constexpr auto NodeIDType = core::PropertyDefinitionBuilder<3>::createProperty("Node ID type")
+ EXTENSIONAPI static constexpr auto NodeIDType = core::PropertyDefinitionBuilder()>::createProperty("Node ID type")
.withDescription("Specifies the type of the provided node ID")
.isRequired(true)
- .withAllowedValues({"Path", "Int", "String"})
+ .withAllowedValues(magic_enum::enum_names())
.build();
EXTENSIONAPI static constexpr auto NodeID = core::PropertyDefinitionBuilder<>::createProperty("Node ID")
.withDescription("Specifies the ID of the root node to traverse. In case of a Path Node ID Type, the path should be provided in the format of 'path/to/node'.")
@@ -84,7 +84,7 @@ class FetchOPCProcessor final : public BaseOPCProcessor {
.build();
EXTENSIONAPI static constexpr auto NameSpaceIndex = core::PropertyDefinitionBuilder<>::createProperty("Namespace index")
.withDescription("The index of the namespace.")
- .withValidator(core::StandardPropertyValidators::INTEGER_VALIDATOR)
+ .withValidator(core::StandardPropertyValidators::UNSIGNED_INTEGER_VALIDATOR)
.withDefaultValue("0")
.isRequired(true)
.build();
@@ -115,6 +115,7 @@ class FetchOPCProcessor final : public BaseOPCProcessor {
EXTENSIONAPI static constexpr auto Relationships = std::array{Success, Failure};
EXTENSIONAPI static constexpr auto NodeIDAttr = core::OutputAttributeDefinition<>{"NodeID", { Success }, "ID of the node."};
+ EXTENSIONAPI static constexpr auto NamespaceIndexAttr = core::OutputAttributeDefinition<>{"Namespace index", {Success}, "Namespace index of the node."};
EXTENSIONAPI static constexpr auto NodeIDTypeAttr = core::OutputAttributeDefinition<>{"NodeID type", { Success }, "Type of the node ID."};
EXTENSIONAPI static constexpr auto BrowsenameAttr = core::OutputAttributeDefinition<>{"Browsename", { Success }, "The browse name of the node."};
EXTENSIONAPI static constexpr auto FullPathAttr = core::OutputAttributeDefinition<>{"Full path", { Success }, "The full path of the node."};
@@ -123,8 +124,8 @@ class FetchOPCProcessor final : public BaseOPCProcessor {
EXTENSIONAPI static constexpr auto TypenameAttr = core::OutputAttributeDefinition<>{"Typename", { Success }, "The type name of the node data."};
EXTENSIONAPI static constexpr auto DatasizeAttr = core::OutputAttributeDefinition<>{"Datasize", { Success }, "The size of the node data."};
- EXTENSIONAPI static constexpr auto OutputAttributes = std::array {NodeIDAttr, NodeIDTypeAttr, BrowsenameAttr, FullPathAttr, SourcetimestampAttr,
- TypenameAttr, DatasizeAttr};
+ EXTENSIONAPI static constexpr auto OutputAttributes = std::array {NodeIDAttr,
+ NamespaceIndexAttr, NodeIDTypeAttr, BrowsenameAttr, FullPathAttr, SourcetimestampAttr, TypenameAttr, DatasizeAttr};
EXTENSIONAPI static constexpr bool SupportsDynamicProperties = false;
EXTENSIONAPI static constexpr bool SupportsDynamicRelationships = false;
@@ -149,7 +150,7 @@ class FetchOPCProcessor final : public BaseOPCProcessor {
uint64_t max_depth_ = 0;
LazyModeOptions lazy_mode_ = LazyModeOptions::Off;
- std::vector translated_node_ids_; // Only used when user provides path, path->nodeid translation is only done once
+ std::vector translated_node_ids_; // Only used when user provides path; cached translation, re-resolved on (re)connect (see path_node_id_resolved_)
};
} // namespace org::apache::nifi::minifi::processors
diff --git a/extensions/opc/include/OPCCommon.h b/extensions/opc/include/OPCCommon.h
index 3664080f39..3d2c177c5a 100644
--- a/extensions/opc/include/OPCCommon.h
+++ b/extensions/opc/include/OPCCommon.h
@@ -24,6 +24,7 @@
#include