diff --git a/.github/references/ubuntu_22_04_clang_arm_manifest.json b/.github/references/ubuntu_22_04_clang_arm_manifest.json
index e4589f8035..fb6489c297 100644
--- a/.github/references/ubuntu_22_04_clang_arm_manifest.json
+++ b/.github/references/ubuntu_22_04_clang_arm_manifest.json
@@ -12206,7 +12206,7 @@
"name": "Keep Source File",
"description": "If true, the file is not deleted after it has been copied to the Content Repository",
"validator": "BOOLEAN_VALIDATOR",
- "required": "false",
+ "required": "true",
"sensitive": "false",
"expressionLanguageScope": "NONE",
"defaultValue": "false"
@@ -12255,7 +12255,7 @@
"name": "Recurse Subdirectories",
"description": "Indicates whether or not to pull files from subdirectories",
"validator": "BOOLEAN_VALIDATOR",
- "required": "false",
+ "required": "true",
"sensitive": "false",
"expressionLanguageScope": "NONE",
"defaultValue": "true"
@@ -12357,7 +12357,7 @@
"Attributes to Ignore": {
"name": "Attributes to Ignore",
"description": "A comma-separated list of Attributes to ignore. If not specified, no attributes will be ignored.",
- "validator": "VALID",
+ "validator": "NON_BLANK_VALIDATOR",
"required": "false",
"sensitive": "false",
"expressionLanguageScope": "NONE"
@@ -12365,7 +12365,7 @@
"Attributes to Log": {
"name": "Attributes to Log",
"description": "A comma-separated list of Attributes to Log. If not specified, all attributes will be logged.",
- "validator": "VALID",
+ "validator": "NON_BLANK_VALIDATOR",
"required": "false",
"sensitive": "false",
"expressionLanguageScope": "NONE"
@@ -12373,7 +12373,7 @@
"FlowFiles To Log": {
"name": "FlowFiles To Log",
"description": "Number of flow files to log. If set to zero all flow files will be logged. Please note that this may block other threads from running if not used judiciously.",
- "validator": "VALID",
+ "validator": "NON_NEGATIVE_INTEGER_VALIDATOR",
"required": "true",
"sensitive": "false",
"expressionLanguageScope": "NONE",
@@ -12460,6 +12460,19 @@
},
{
"propertyDescriptors": {
+ "Dummy Controller Service": {
+ "typeProvidedByValue": {
+ "type": "minifi_rs_playground.controller_services.dummy_controller_service.DummyControllerService",
+ "group": "org.apache.nifi.minifi.rust.test",
+ "artifact": "minifi_rs_playground"
+ },
+ "name": "Dummy Controller Service",
+ "description": "Optional dummy controller service",
+ "validator": "VALID",
+ "required": "false",
+ "sensitive": "false",
+ "expressionLanguageScope": "NONE"
+ },
"Lorem Ipsum Controller Service": {
"typeProvidedByValue": {
"type": "minifi_rs_playground.controller_services.lorem_ipsum_controller_service.LoremIpsumControllerService",
diff --git a/minifi_rust/extensions/minifi_rs_playground/Cargo.toml b/minifi_rust/extensions/minifi_rs_playground/Cargo.toml
index 8d8682660c..ec90190e37 100644
--- a/minifi_rust/extensions/minifi_rs_playground/Cargo.toml
+++ b/minifi_rust/extensions/minifi_rs_playground/Cargo.toml
@@ -16,6 +16,7 @@ hex = "0.4.3"
strum_macros = "0.28.0"
lipsum = "0.9.1"
+
[dev-dependencies]
tempfile = "3.22.0"
filetime = "0.2.26"
diff --git a/minifi_rust/extensions/minifi_rs_playground/features/controller_apis.feature b/minifi_rust/extensions/minifi_rs_playground/features/controller_apis.feature
index c93f896160..8bbc2dd7e3 100644
--- a/minifi_rust/extensions/minifi_rs_playground/features/controller_apis.feature
+++ b/minifi_rust/extensions/minifi_rs_playground/features/controller_apis.feature
@@ -23,6 +23,6 @@ Feature: Testing controller service api casting
And the "Extra information" property of the Wolfie the magical controller service is set to "The dog (Canis familiaris or Canis lupus familiaris) is a domesticated descendant of wolves."
When the MiNiFi instance starts up
- Then the Minifi logs contain the following message: "[minifi_rs_playground::processors::zoo_processor::ZooProcessorRs] [critical] Can DogControllerRs { has_jetpack: true, extra_info: "The dog (Canis familiaris or Canis lupus familiaris) is a domesticated descendant of wolves." } fly? true" in less than 10 seconds
+ Then the Minifi logs contain the following message: "[minifi_rs_playground::processors::zoo_processor::ZooProcessorRs] [critical] Can DogControllerRs { has_jetpack: true, extra_info: Some("The dog (Canis familiaris or Canis lupus familiaris) is a domesticated descendant of wolves.") } fly?" in less than 10 seconds
And the Minifi logs do not contain errors
And the Minifi logs do not contain warnings
diff --git a/minifi_rust/extensions/minifi_rs_playground/minifi_rs_playground.md b/minifi_rust/extensions/minifi_rs_playground/minifi_rs_playground.md
index 4078b7301a..e05adf0e0e 100644
--- a/minifi_rust/extensions/minifi_rs_playground/minifi_rs_playground.md
+++ b/minifi_rust/extensions/minifi_rs_playground/minifi_rs_playground.md
@@ -130,24 +130,24 @@ RUST TEST PROCESSOR: Creates FlowFiles from files in a directory. MiNiFi will ig
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 |
-|-------------------------|---------------|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| **Batch Size** | 10 | | The maximum number of files to pull in each iteration |
-| **Ignore Hidden Files** | true | true false | Indicates whether or not hidden files should be ignored |
-| **Input Directory** | | | The input directory from which to pull files **Supports Expression Language: true** |
-| Keep Source File | false | true false | If true, the file is not deleted after it has been copied to the Content Repository |
-| Maximum File Age | | | The maximum age that a file must be in order to be pulled; any file older than this amount of time (according to last modification date) will be ignored |
-| Maximum File Size | | | The maximum size that a file can be in order to be pulled |
-| Minimum File Age | | | The minimum age that a file must be in order to be pulled; any file younger than this amount of time (according to last modification date) will be ignored |
-| Minimum File Size | | | The minimum size that a file can be in order to be pulled |
-| Polling Interval | | | Indicates how long to wait before performing a directory listing |
-| Recurse Subdirectories | true | true false | Indicates whether or not to pull files from subdirectories |
+| Name | Default Value | Allowable Values | Description |
+|----------------------------|---------------|------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| **Batch Size** | 10 | | The maximum number of files to pull in each iteration |
+| **Ignore Hidden Files** | true | true false | Indicates whether or not hidden files should be ignored |
+| **Input Directory** | | | The input directory from which to pull files **Supports Expression Language: true** |
+| **Keep Source File** | false | true false | If true, the file is not deleted after it has been copied to the Content Repository |
+| Maximum File Age | | | The maximum age that a file must be in order to be pulled; any file older than this amount of time (according to last modification date) will be ignored |
+| Maximum File Size | | | The maximum size that a file can be in order to be pulled |
+| Minimum File Age | | | The minimum age that a file must be in order to be pulled; any file younger than this amount of time (according to last modification date) will be ignored |
+| Minimum File Size | | | The minimum size that a file can be in order to be pulled |
+| Polling Interval | | | Indicates how long to wait before performing a directory listing |
+| **Recurse Subdirectories** | true | true false | Indicates whether or not to pull files from subdirectories |
### Relationships
-| Name | Description |
-|---------|----------------------------------------------|
-| success | FlowFiles are transferred here after logging |
+| Name | Description |
+|---------|--------------------------------------------|
+| success | The created FlowFiles are transferred here |
### Output Attributes
diff --git a/minifi_rust/extensions/minifi_rs_playground/src/controller_services/dog_controller_service.rs b/minifi_rust/extensions/minifi_rs_playground/src/controller_services/dog_controller_service.rs
index df25212130..d3307a3b54 100644
--- a/minifi_rust/extensions/minifi_rs_playground/src/controller_services/dog_controller_service.rs
+++ b/minifi_rust/extensions/minifi_rs_playground/src/controller_services/dog_controller_service.rs
@@ -18,42 +18,26 @@
use crate::controller_services::animal_controller_apis::{
CanFlyControllerApi, NumberOfLegsControllerApi,
};
-use minifi_native::ControllerServiceApi;
use minifi_native::macros::ComponentIdentifier;
use minifi_native::{
- ControllerServiceDefinition, EnableControllerService, GetProperty, Logger, MinifiError,
- Property, ProvidedInterface, StandardPropertyValidator, create_provided_interface,
+ ControllerServiceApi, ControllerServiceDefinition, EnableControllerService, GetProperty,
+ Logger, MinifiError, Property, PropertyDefinition, ProvidedInterface,
+ create_provided_interface, property_definitions,
};
-pub(crate) const HAS_JETPACK: Property = Property {
- name: "Has Jetpack",
- description: "Whether or not the dog has a jetpack",
- is_required: true,
- is_sensitive: false,
- supports_expr_lang: false,
- default_value: Some("false"),
- validator: StandardPropertyValidator::BoolValidator,
- allowed_values: &[],
- allowed_type: None,
-};
+pub(crate) const HAS_JETPACK: Property =
+ Property::new("Has Jetpack", "Whether or not the dog has a jetpack").with_default("false");
-pub(crate) const EXTRA_INFO: Property = Property {
- name: "Extra information",
- description: "We need this to verify the casting was done correctly",
- is_required: false,
- is_sensitive: false,
- supports_expr_lang: false,
- default_value: None,
- validator: StandardPropertyValidator::AlwaysValidValidator,
- allowed_values: &[],
- allowed_type: None,
-};
+pub(crate) const EXTRA_INFO: Property