This is an automated email from the ASF dual-hosted git repository.

fgerlits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git


The following commit(s) were added to refs/heads/main by this push:
     new 689397348 MINIFICPP-2662 - Remove dependent and exclusive properties
689397348 is described below

commit 689397348a470136fbcea520faf308d636faba0a
Author: Adam Debreceni <[email protected]>
AuthorDate: Mon Nov 10 12:32:49 2025 +0100

    MINIFICPP-2662 - Remove dependent and exclusive properties
    
    Signed-off-by: Ferenc Gerlits <[email protected]>
    
    Closes #2060
---
 .../include/core/PropertyDefinitionBuilder.h       | 44 +++++---------
 core-framework/src/core/Property.cpp               | 19 +-----
 extensions/smb/PutSmb.h                            |  3 +-
 extensions/smb/SmbConnectionControllerService.h    |  2 -
 extensions/splunk/SplunkHECProcessor.h             |  3 +-
 .../standard-processors/processors/InvokeHTTP.h    |  3 +-
 .../standard-processors/processors/PutFile.h       |  3 +-
 .../tests/unit/ManifestTests.cpp                   |  4 +-
 .../tests/unit/YamlConfigurationTests.cpp          | 70 ----------------------
 .../src/core/flow/StructuredConfiguration.cpp      | 36 -----------
 .../src/core/state/nodes/AgentInformation.cpp      | 14 -----
 minifi-api/include/minifi-cpp/core/Property.h      |  9 +--
 .../include/minifi-cpp/core/PropertyDefinition.h   | 17 ++----
 13 files changed, 28 insertions(+), 199 deletions(-)

diff --git a/core-framework/include/core/PropertyDefinitionBuilder.h 
b/core-framework/include/core/PropertyDefinitionBuilder.h
index c99038041..221f5d917 100644
--- a/core-framework/include/core/PropertyDefinitionBuilder.h
+++ b/core-framework/include/core/PropertyDefinitionBuilder.h
@@ -29,76 +29,64 @@ template<typename... Types>
 inline constexpr auto TypeNames = std::array<std::string_view, 
sizeof...(Types)>{core::className<Types>()...};
 }
 
-template<size_t NumAllowedValues = 0, size_t NumDependentProperties = 0, 
size_t NumExclusiveOfProperties = 0>
+template<size_t NumAllowedValues = 0>
 struct PropertyDefinitionBuilder {
-  static constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> 
createProperty(std::string_view name) {
-    PropertyDefinitionBuilder<NumAllowedValues, NumDependentProperties, 
NumExclusiveOfProperties> builder;
+  static constexpr PropertyDefinitionBuilder<NumAllowedValues> 
createProperty(std::string_view name) {
+    PropertyDefinitionBuilder<NumAllowedValues> builder;
     builder.property.name = name;
     return builder;
   }
 
-  static constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> 
createProperty(std::string_view name, std::string_view display_name) {
-    PropertyDefinitionBuilder<NumAllowedValues, NumDependentProperties, 
NumExclusiveOfProperties> builder;
+  static constexpr PropertyDefinitionBuilder<NumAllowedValues> 
createProperty(std::string_view name, std::string_view display_name) {
+    PropertyDefinitionBuilder<NumAllowedValues> builder;
     builder.property.name = name;
     builder.property.display_name = display_name;
     return builder;
   }
 
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> 
withDescription(std::string_view description) {
+  constexpr PropertyDefinitionBuilder<NumAllowedValues> 
withDescription(std::string_view description) {
     property.description = description;
     return *this;
   }
 
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> isRequired(bool required) {
+  constexpr PropertyDefinitionBuilder<NumAllowedValues> isRequired(bool 
required) {
     property.is_required = required;
     return *this;
   }
 
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> isSensitive(bool sensitive) {
+  constexpr PropertyDefinitionBuilder<NumAllowedValues> isSensitive(bool 
sensitive) {
     property.is_sensitive = sensitive;
     return *this;
   }
 
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> 
supportsExpressionLanguage(bool supports_expression_language) {
+  constexpr PropertyDefinitionBuilder<NumAllowedValues> 
supportsExpressionLanguage(bool supports_expression_language) {
     property.supports_expression_language = supports_expression_language;
     return *this;
   }
 
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> 
withDefaultValue(std::string_view default_value) {
+  constexpr PropertyDefinitionBuilder<NumAllowedValues> 
withDefaultValue(std::string_view default_value) {
     property.default_value = std::optional<std::string_view>{default_value};  
// workaround for gcc 11.1; on gcc 11.3 and later, `property.default_value = 
default_value` works, too
     return *this;
   }
 
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> withAllowedValues(
+  constexpr PropertyDefinitionBuilder<NumAllowedValues> withAllowedValues(
       std::array<std::string_view, NumAllowedValues> allowed_values) {
     property.allowed_values = allowed_values;
     return *this;
   }
 
   template<typename... AllowedTypes>
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> withAllowedTypes() {
+  constexpr PropertyDefinitionBuilder<NumAllowedValues> withAllowedTypes() {
     property.allowed_types = {detail::TypeNames<AllowedTypes...>};
     return *this;
   }
 
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> withDependentProperties(
-      std::array<std::string_view, NumDependentProperties> 
dependent_properties) {
-    property.dependent_properties = dependent_properties;
-    return *this;
-  }
-
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> withExclusiveOfProperties(
-      std::array<std::pair<std::string_view, std::string_view>, 
NumExclusiveOfProperties> exclusive_of_properties) {
-    property.exclusive_of_properties = exclusive_of_properties;
-    return *this;
-  }
-
-  constexpr PropertyDefinitionBuilder<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties> withValidator(const 
PropertyValidator& property_validator) {
+  constexpr PropertyDefinitionBuilder<NumAllowedValues> withValidator(const 
PropertyValidator& property_validator) {
     property.validator = gsl::make_not_null(&property_validator);
     return *this;
   }
 
-  constexpr PropertyDefinition<NumAllowedValues, NumDependentProperties, 
NumExclusiveOfProperties> build() {
+  constexpr PropertyDefinition<NumAllowedValues> build() {
     if (property.name.size() == 0) {
       throw std::logic_error("A Property must have a name");
     }
@@ -113,7 +101,7 @@ struct PropertyDefinitionBuilder {
     return property;
   }
 
-  PropertyDefinition<NumAllowedValues, NumDependentProperties, 
NumExclusiveOfProperties> property{
+  PropertyDefinition<NumAllowedValues> property{
     .name = {},
     .display_name = {},
     .description = {},
@@ -121,8 +109,6 @@ struct PropertyDefinitionBuilder {
     .is_sensitive = false,
     .allowed_values = {},
     .allowed_types = {},
-    .dependent_properties = {},
-    .exclusive_of_properties = {},
     .default_value = {},
     .validator = 
gsl::make_not_null(&StandardPropertyValidators::ALWAYS_VALID_VALIDATOR),
     .supports_expression_language = false,
diff --git a/core-framework/src/core/Property.cpp 
b/core-framework/src/core/Property.cpp
index 8af7fa490..a55159cab 100644
--- a/core-framework/src/core/Property.cpp
+++ b/core-framework/src/core/Property.cpp
@@ -68,22 +68,10 @@ bool Property::operator<(const Property& right) const {
   return name_ < right.name_;
 }
 
-std::vector<std::string> Property::getDependentProperties() const {
-  return dependent_properties_;
-}
-
-std::vector<std::pair<std::string, std::string>> 
Property::getExclusiveOfProperties() const {
-  return exclusive_of_properties_;
-}
-
 namespace {
 inline std::vector<std::string> createStrings(std::span<const 
std::string_view> string_views) {
   return ranges::views::transform(string_views, [](const auto& string_view) { 
return std::string{string_view}; }) | ranges::to<std::vector>;
 }
-
-inline std::vector<std::pair<std::string, std::string>> 
createStrings(std::span<const std::pair<std::string_view, std::string_view>> 
pairs_of_string_views) {
-  return ranges::views::transform(pairs_of_string_views, [](const auto& 
pair_of_string_views) { return std::pair<std::string, 
std::string>(pair_of_string_views); }) | ranges::to<std::vector>;
-}
 }  // namespace
 
 Property::Property(const PropertyReference& compile_time_property)
@@ -92,8 +80,6 @@ Property::Property(const PropertyReference& 
compile_time_property)
       description_(compile_time_property.description),
       is_required_(compile_time_property.is_required),
       is_sensitive_(compile_time_property.is_sensitive),
-      
dependent_properties_(createStrings(compile_time_property.dependent_properties)),
-      
exclusive_of_properties_(createStrings(compile_time_property.exclusive_of_properties)),
       is_collection_(false),
       default_value_(compile_time_property.default_value),
       allowed_values_(createStrings(compile_time_property.allowed_values)),
@@ -102,13 +88,10 @@ Property::Property(const PropertyReference& 
compile_time_property)
       supports_el_(compile_time_property.supports_expression_language),
       is_transient_(false) {}
 
-Property::Property(std::string name, std::string description, const 
std::string& value, bool is_required, std::vector<std::string> 
dependent_properties,
-    std::vector<std::pair<std::string, std::string>> exclusive_of_properties)
+Property::Property(std::string name, std::string description, const 
std::string& value, bool is_required)
     : name_(std::move(name)),
       description_(std::move(description)),
       is_required_(is_required),
-      dependent_properties_(std::move(dependent_properties)),
-      exclusive_of_properties_(std::move(exclusive_of_properties)),
       is_collection_(false),
       default_value_(value),
       validator_(&StandardPropertyValidators::ALWAYS_VALID_VALIDATOR),
diff --git a/extensions/smb/PutSmb.h b/extensions/smb/PutSmb.h
index 37ff29242..c0ec5a9ce 100644
--- a/extensions/smb/PutSmb.h
+++ b/extensions/smb/PutSmb.h
@@ -57,11 +57,10 @@ class PutSmb final : public core::ProcessorImpl {
       
.withDefaultValue(magic_enum::enum_name(FileExistsResolutionStrategy::fail))
       
.withAllowedValues(magic_enum::enum_names<FileExistsResolutionStrategy>())
       .build();
-  EXTENSIONAPI static constexpr auto CreateMissingDirectories = 
core::PropertyDefinitionBuilder<0, 0, 1>::createProperty("Create Missing 
Directories")
+  EXTENSIONAPI static constexpr auto CreateMissingDirectories = 
core::PropertyDefinitionBuilder<0>::createProperty("Create Missing Directories")
       .withDescription("If true, then missing destination directories will be 
created. If false, flowfiles are penalized and sent to failure.")
       .withDefaultValue("true")
       .isRequired(true)
-      .withDependentProperties({Directory.name})
       .build();
 
   EXTENSIONAPI static constexpr auto Properties = 
std::to_array<core::PropertyReference>({ ConnectionControllerService, 
Directory, ConflictResolution, CreateMissingDirectories});
diff --git a/extensions/smb/SmbConnectionControllerService.h 
b/extensions/smb/SmbConnectionControllerService.h
index a1ddcb2a0..22e3e5377 100644
--- a/extensions/smb/SmbConnectionControllerService.h
+++ b/extensions/smb/SmbConnectionControllerService.h
@@ -53,12 +53,10 @@ class SmbConnectionControllerService : public 
core::controller::ControllerServic
   EXTENSIONAPI static constexpr auto Username  = 
core::PropertyDefinitionBuilder<>::createProperty("Username")
       .withDescription("The username used for authentication. If no username 
is set then anonymous authentication is attempted.")
       .isRequired(false)
-      .withDependentProperties({"Password"})
       .build();
   EXTENSIONAPI static constexpr auto Password  = 
core::PropertyDefinitionBuilder<>::createProperty("Password")
       .withDescription("The password used for authentication. Required if 
Username is set.")
       .isRequired(false)
-      .withDependentProperties({"Username"})
       .isSensitive(true)
       .build();
 
diff --git a/extensions/splunk/SplunkHECProcessor.h 
b/extensions/splunk/SplunkHECProcessor.h
index 25a78be28..b13df1773 100644
--- a/extensions/splunk/SplunkHECProcessor.h
+++ b/extensions/splunk/SplunkHECProcessor.h
@@ -55,10 +55,9 @@ class SplunkHECProcessor : public core::ProcessorImpl {
       .withDescription("Identifier of the used request channel.")
       .isRequired(true)
       .build();
-  EXTENSIONAPI static constexpr auto SSLContext = 
core::PropertyDefinitionBuilder<0, 0, 1>::createProperty("SSL Context Service")
+  EXTENSIONAPI static constexpr auto SSLContext = 
core::PropertyDefinitionBuilder<0>::createProperty("SSL Context Service")
       .withDescription("The SSL Context Service used to provide client 
certificate information for TLS/SSL (https) connections.")
       .isRequired(false)
-      .withExclusiveOfProperties({{{"Hostname", "^http:.*$"}}})
       .withAllowedTypes<minifi::controllers::SSLContextServiceInterface>()
       .build();
   EXTENSIONAPI static constexpr auto Properties = 
std::to_array<core::PropertyReference>({
diff --git a/extensions/standard-processors/processors/InvokeHTTP.h 
b/extensions/standard-processors/processors/InvokeHTTP.h
index 12162c023..d63a64387 100644
--- a/extensions/standard-processors/processors/InvokeHTTP.h
+++ b/extensions/standard-processors/processors/InvokeHTTP.h
@@ -172,11 +172,10 @@ class InvokeHTTP : public core::ProcessorImpl {
   EXTENSIONAPI static constexpr auto AttributesToSend = 
core::PropertyDefinitionBuilder<>::createProperty("Attributes to Send")
       .withDescription("Regular expression that defines which attributes to 
send as HTTP headers in the request. If not defined, no attributes are sent as 
headers.")
       .build();
-  EXTENSIONAPI static constexpr auto SSLContext = 
core::PropertyDefinitionBuilder<0, 0, 1>::createProperty("SSL Context Service")
+  EXTENSIONAPI static constexpr auto SSLContext = 
core::PropertyDefinitionBuilder<0>::createProperty("SSL Context Service")
       .withDescription("The SSL Context Service used to provide client 
certificate information for TLS/SSL (https) connections.")
       .isRequired(false)
       .withAllowedTypes<controllers::SSLContextServiceInterface>()
-      .withExclusiveOfProperties({{{"Remote URL", "^http:.*$"}}})
       .build();
   EXTENSIONAPI static constexpr auto ProxyHost = 
core::PropertyDefinitionBuilder<>::createProperty("Proxy Host")
       .withDescription("The fully qualified hostname or IP address of the 
proxy server")
diff --git a/extensions/standard-processors/processors/PutFile.h 
b/extensions/standard-processors/processors/PutFile.h
index 186e64720..27f40b50e 100644
--- a/extensions/standard-processors/processors/PutFile.h
+++ b/extensions/standard-processors/processors/PutFile.h
@@ -69,12 +69,11 @@ class PutFile : public core::ProcessorImpl {
       
.withDefaultValue(magic_enum::enum_name(FileExistsResolutionStrategy::fail))
       
.withAllowedValues(magic_enum::enum_names<FileExistsResolutionStrategy>())
       .build();
-  EXTENSIONAPI static constexpr auto CreateDirs = 
core::PropertyDefinitionBuilder<0, 1>::createProperty("Create Missing 
Directories")
+  EXTENSIONAPI static constexpr auto CreateDirs = 
core::PropertyDefinitionBuilder<0>::createProperty("Create Missing Directories")
       .withDescription("If true, then missing destination directories will be 
created. If false, flowfiles are penalized and sent to failure.")
       .withDefaultValue("true")
       .withValidator(core::StandardPropertyValidators::BOOLEAN_VALIDATOR)
       .isRequired(true)
-      .withDependentProperties({Directory.name})
       .build();
   EXTENSIONAPI static constexpr auto MaxDestFiles = 
core::PropertyDefinitionBuilder<>::createProperty("Maximum File Count")
       .withDescription("Specifies the maximum number of files that can exist 
in the output directory")
diff --git a/extensions/standard-processors/tests/unit/ManifestTests.cpp 
b/extensions/standard-processors/tests/unit/ManifestTests.cpp
index 2ba13b0ef..638ea37f2 100644
--- a/extensions/standard-processors/tests/unit/ManifestTests.cpp
+++ b/extensions/standard-processors/tests/unit/ManifestTests.cpp
@@ -74,7 +74,7 @@ TEST_CASE("Test Valid Regex", "[validRegex]") {
   const auto &prop_descriptors = processor_with_properties.children[0];
   REQUIRE_FALSE(prop_descriptors.children.empty());
   const auto &prop_0 = prop_descriptors.children[0];
-  REQUIRE(prop_0.children.size() >= 7);
+  REQUIRE(prop_0.children.size() >= 6);
   CHECK("required" == prop_0.children[3].name);
   CHECK("sensitive" == prop_0.children[4].name);
   CHECK("expressionLanguageScope" == prop_0.children[5].name);
@@ -138,7 +138,7 @@ TEST_CASE("Test Dependent", "[dependent]") {
   const auto &prop_descriptors = proc_0.children[0];
   REQUIRE(prop_descriptors.children.size() >= 3);
   const auto &prop_0 = prop_descriptors.children[1];
-  REQUIRE(prop_0.children.size() >= 7);
+  REQUIRE(prop_0.children.size() >= 6);
   CHECK("required" == prop_0.children[3].name);
   CHECK("sensitive" == prop_0.children[4].name);
   CHECK("expressionLanguageScope" == prop_0.children[5].name);
diff --git 
a/extensions/standard-processors/tests/unit/YamlConfigurationTests.cpp 
b/extensions/standard-processors/tests/unit/YamlConfigurationTests.cpp
index c36fbcffa..1f815d3bd 100644
--- a/extensions/standard-processors/tests/unit/YamlConfigurationTests.cpp
+++ b/extensions/standard-processors/tests/unit/YamlConfigurationTests.cpp
@@ -594,76 +594,6 @@ class DummyComponent : public 
core::ConfigurableComponentImpl, public core::Core
   }
 };
 
-TEST_CASE("Test Dependent Property", "[YamlConfigurationDependentProperty]") {
-  ConfigurationTestController test_controller;
-
-  core::YamlConfiguration yamlConfig(test_controller.getContext());
-  const auto component = std::make_shared<DummyComponent>();
-  component->setSupportedProperties(std::to_array<core::PropertyReference>({
-    core::PropertyDefinitionBuilder<>::createProperty("Prop 
A").withDescription("Prop A desc").withDefaultValue("val 
A").isRequired(true).build(),
-    core::PropertyDefinitionBuilder<0, 1>::createProperty("Prop 
B").withDescription("Prop B desc").withDefaultValue("val 
B").isRequired(true).withDependentProperties({ "Prop A" }).build()
-  }));
-  yamlConfig.validateComponentProperties(*component, "component A", "section 
A");
-  REQUIRE(true);  // Expected to get here w/o any exceptions
-}
-
-TEST_CASE("Test Dependent Property 2", 
"[YamlConfigurationDependentProperty2]") {
-  ConfigurationTestController test_controller;
-
-  core::YamlConfiguration yamlConfig(test_controller.getContext());
-  const auto component = std::make_shared<DummyComponent>();
-  component->setSupportedProperties(std::to_array<core::PropertyReference>({
-    core::PropertyDefinitionBuilder<>::createProperty("Prop 
A").withDescription("Prop A desc").isRequired(false).build(),
-    core::PropertyDefinitionBuilder<0, 1>::createProperty("Prop 
B").withDescription("Prop B desc").withDefaultValue("val 
B").isRequired(true).withDependentProperties({ "Prop A" }).build()
-  }));
-  bool config_failed = false;
-  try {
-    yamlConfig.validateComponentProperties(*component, "component A", "section 
A");
-  } catch (const std::exception &e) {
-    config_failed = true;
-    REQUIRE("Unable to parse configuration file for component named 'component 
A' because property "
-        "'Prop B' depends on property 'Prop A' which is not set "
-        "[in 'section A' section of configuration file]" == 
std::string(e.what()));
-  }
-  REQUIRE(config_failed);
-}
-
-TEST_CASE("Test Exclusive Property", "[YamlConfigurationExclusiveOfProperty]") 
{
-  ConfigurationTestController test_controller;
-
-  core::YamlConfiguration yamlConfig(test_controller.getContext());
-  const auto component = std::make_shared<DummyComponent>();
-  component->setSupportedProperties(std::to_array<core::PropertyReference>({
-    core::PropertyDefinitionBuilder<>::createProperty("Prop 
A").withDescription("Prop A desc").withDefaultValue("val 
A").isRequired(true).build(),
-    core::PropertyDefinitionBuilder<0, 0, 1>::createProperty("Prop 
B").withDescription("Prop B desc").withDefaultValue("val B").isRequired(true)
-        .withExclusiveOfProperties({{ { "Prop A", "^abcd.*$" } }}).build()
-  }));
-  yamlConfig.validateComponentProperties(*component, "component A", "section 
A");
-  REQUIRE(true);  // Expected to get here w/o any exceptions
-}
-
-TEST_CASE("Test Exclusive Property 2", 
"[YamlConfigurationExclusiveOfProperty2]") {
-  ConfigurationTestController test_controller;
-
-  core::YamlConfiguration yamlConfig(test_controller.getContext());
-  const auto component = std::make_shared<DummyComponent>();
-  component->setSupportedProperties(std::to_array<core::PropertyReference>({
-    core::PropertyDefinitionBuilder<>::createProperty("Prop 
A").withDescription("Prop A desc").withDefaultValue("val 
A").isRequired(true).build(),
-    core::PropertyDefinitionBuilder<0, 0, 1>::createProperty("Prop 
B").withDescription("Prop B desc").withDefaultValue("val B").isRequired(true)
-        .withExclusiveOfProperties({{ { "Prop A", "^val.*$" } }}).build()
-  }));
-  bool config_failed = false;
-  try {
-    yamlConfig.validateComponentProperties(*component, "component A", "section 
A");
-  } catch (const std::exception &e) {
-    config_failed = true;
-    REQUIRE("Unable to parse configuration file for component named 'component 
A' because "
-        "property 'Prop B' must not be set when the value of property 'Prop A' 
matches '^val.*$' "
-        "[in 'section A' section of configuration file]" == 
std::string(e.what()));
-  }
-  REQUIRE(config_failed);
-}
-
 TEST_CASE("Test YAML Config With Funnel", "[YamlConfiguration]") {
   ConfigurationTestController test_controller;
 
diff --git a/libminifi/src/core/flow/StructuredConfiguration.cpp 
b/libminifi/src/core/flow/StructuredConfiguration.cpp
index aa5e9cf64..db738846a 100644
--- a/libminifi/src/core/flow/StructuredConfiguration.cpp
+++ b/libminifi/src/core/flow/StructuredConfiguration.cpp
@@ -1055,42 +1055,6 @@ void 
StructuredConfiguration::validateComponentProperties(ConfigurableComponent&
       }
     }
   }
-
-  // Validate dependent properties
-  for (const auto & [property_name, property] : component_properties) {
-    const auto &dep_props = property.getDependentProperties();
-
-    const auto property_value = property.getValue();
-    if (!property_value) {
-      continue;
-    }
-
-    for (const auto &dep_prop_key : dep_props) {
-      if (auto dep_prop_value = 
component_properties.at(dep_prop_key).getValue(); !dep_prop_value) {
-        std::string reason = utils::string::join_pack("property '", 
property.getName(),
-            "' depends on property '", dep_prop_key, "' which is not set");
-        raiseComponentError(component_name, section, reason);
-      }
-    }
-  }
-
-  // Validate mutually-exclusive properties
-  for (const auto& [prop_name, prop] : component_properties) {
-    const auto& excl_props = prop.getExclusiveOfProperties();
-
-    if (!prop.getValue()) {
-      continue;
-    }
-
-    for (const auto &[excl_prop_key, excl_prop_regex] : excl_props) {
-      utils::Regex excl_expr(excl_prop_regex);
-      if 
(utils::regexMatch(component_properties.at(excl_prop_key).getValue().value_or(""),
 excl_expr)) {
-        std::string reason = utils::string::join_pack("property '", 
prop.getName(),
-            "' must not be set when the value of property '", excl_prop_key, 
"' matches '", excl_prop_regex, "'");
-        raiseComponentError(component_name, section, reason);
-      }
-    }
-  }
 }
 
 void StructuredConfiguration::raiseComponentError(const std::string 
&component_name, const std::string &section, const std::string &reason) const {
diff --git a/libminifi/src/core/state/nodes/AgentInformation.cpp 
b/libminifi/src/core/state/nodes/AgentInformation.cpp
index de4c12263..92952ae81 100644
--- a/libminifi/src/core/state/nodes/AgentInformation.cpp
+++ b/libminifi/src/core/state/nodes/AgentInformation.cpp
@@ -53,18 +53,6 @@ void ComponentManifest::serializeClassDescription(const 
std::vector<ClassDescrip
       SerializedResponseNode props{.name = "propertyDescriptors"};
       for (auto&& prop : group.class_properties_) {
         SerializedResponseNode child = {.name = prop.getName()};
-        SerializedResponseNode descriptorDependentProperties{.name = 
"dependentProperties"};
-        for (const auto &propName : prop.getDependentProperties()) {
-          SerializedResponseNode descriptorDependentProperty{.name = propName};
-          
descriptorDependentProperties.children.push_back(descriptorDependentProperty);
-        }
-
-        SerializedResponseNode descriptorExclusiveOfProperties{.name = 
"exclusiveOfProperties"};
-
-        for (const auto &exclusiveProp : prop.getExclusiveOfProperties()) {
-          SerializedResponseNode descriptorExclusiveOfProperty{.name = 
exclusiveProp.first, .value = exclusiveProp.second};
-          
descriptorExclusiveOfProperties.children.push_back(descriptorExclusiveOfProperty);
-        }
 
         const auto &allowed_types = prop.getAllowedTypes();
         if (!allowed_types.empty()) {
@@ -98,8 +86,6 @@ void ComponentManifest::serializeClassDescription(const 
std::vector<ClassDescrip
         if (const auto default_value = prop.getDefaultValue()) {
           child.children.push_back({.name = "defaultValue", .value = 
*default_value});  // NOLINT(cppcoreguidelines-slicing)
         }
-        child.children.push_back(descriptorDependentProperties);
-        child.children.push_back(descriptorExclusiveOfProperties);
 
         if (!prop.getAllowedValues().empty()) {
           SerializedResponseNode allowedValues{.name = "allowableValues", 
.array = true};
diff --git a/minifi-api/include/minifi-cpp/core/Property.h 
b/minifi-api/include/minifi-cpp/core/Property.h
index a572479b0..68f09d975 100644
--- a/minifi-api/include/minifi-cpp/core/Property.h
+++ b/minifi-api/include/minifi-cpp/core/Property.h
@@ -34,8 +34,7 @@ namespace org::apache::nifi::minifi::core {
 
 class Property final {
  public:
-  Property(std::string name, std::string description, const std::string 
&value, bool is_required, std::vector<std::string> dependent_properties,
-      std::vector<std::pair<std::string, std::string>> 
exclusive_of_properties);
+  Property(std::string name, std::string description, const std::string 
&value, bool is_required);
 
   Property(std::string name, std::string description, const std::string 
&value);
 
@@ -70,11 +69,9 @@ class Property final {
   bool getRequired() const;
   bool isSensitive() const;
   bool supportsExpressionLanguage() const;
-  std::vector<std::string> getDependentProperties() const;
-  std::vector<std::pair<std::string, std::string>> getExclusiveOfProperties() 
const;
   std::vector<std::string> getValues();
   PropertyReference getReference() const {
-    return PropertyReference(name_, display_name_, description_, is_required_, 
is_sensitive_, {}, {}, {}, {}, default_value_, validator_, supports_el_);
+    return PropertyReference(name_, display_name_, description_, is_required_, 
is_sensitive_, {}, {}, default_value_, validator_, supports_el_);
   }
 
   void setSupportsExpressionLanguage(bool supportEl);
@@ -91,8 +88,6 @@ class Property final {
   std::string description_;
   bool is_required_;
   bool is_sensitive_ = false;
-  std::vector<std::string> dependent_properties_;
-  std::vector<std::pair<std::string, std::string>> exclusive_of_properties_;
   bool is_collection_;
 
   std::optional<std::string> default_value_ = std::nullopt;
diff --git a/minifi-api/include/minifi-cpp/core/PropertyDefinition.h 
b/minifi-api/include/minifi-cpp/core/PropertyDefinition.h
index 0e4469918..182cd2e56 100644
--- a/minifi-api/include/minifi-cpp/core/PropertyDefinition.h
+++ b/minifi-api/include/minifi-cpp/core/PropertyDefinition.h
@@ -27,7 +27,7 @@
 
 namespace org::apache::nifi::minifi::core {
 
-template<size_t NumAllowedValues = 0, size_t NumDependentProperties = 0, 
size_t NumExclusiveOfProperties = 0>
+template<size_t NumAllowedValues = 0>
 struct PropertyDefinition {
   std::string_view name;
   std::string_view display_name;
@@ -36,8 +36,6 @@ struct PropertyDefinition {
   bool is_sensitive;
   std::array<std::string_view, NumAllowedValues> allowed_values;
   std::span<const std::string_view> allowed_types;
-  std::array<std::string_view, NumDependentProperties> dependent_properties;
-  std::array<std::pair<std::string_view, std::string_view>, 
NumExclusiveOfProperties> exclusive_of_properties;
   std::optional<std::string_view> default_value;
   gsl::not_null<const PropertyValidator*> validator;
   bool supports_expression_language;
@@ -53,14 +51,12 @@ struct PropertyReference {
   bool is_sensitive = false;
   std::span<const std::string_view> allowed_values;
   std::span<const std::string_view> allowed_types;
-  std::span<const std::string_view> dependent_properties;
-  std::span<const std::pair<std::string_view, std::string_view>> 
exclusive_of_properties;
   std::optional<std::string_view> default_value;
   gsl::not_null<const PropertyValidator*> validator;
   bool supports_expression_language = false;
 
-  template<size_t NumAllowedValues = 0, size_t NumDependentProperties = 0, 
size_t NumExclusiveOfProperties = 0>
-  constexpr PropertyReference(const PropertyDefinition<NumAllowedValues, 
NumDependentProperties, NumExclusiveOfProperties>& property_definition)  // 
NOLINT: non-explicit on purpose
+  template<size_t NumAllowedValues = 0>
+  constexpr PropertyReference(const PropertyDefinition<NumAllowedValues>& 
property_definition)  // NOLINT: non-explicit on purpose
       : name{property_definition.name},
         display_name{property_definition.display_name},
         description{property_definition.description},
@@ -68,15 +64,12 @@ struct PropertyReference {
         is_sensitive{property_definition.is_sensitive},
         allowed_values{property_definition.allowed_values},
         allowed_types{property_definition.allowed_types},
-        dependent_properties{property_definition.dependent_properties},
-        exclusive_of_properties{property_definition.exclusive_of_properties},
         default_value{property_definition.default_value},
         validator{property_definition.validator},
         
supports_expression_language{property_definition.supports_expression_language} 
{}
 
   PropertyReference(const std::string_view name, const std::string_view 
display_name, const std::string_view description, const bool is_required, const 
bool is_sensitive,
-      const std::span<const std::string_view> allowed_values, std::span<const 
std::string_view> allowed_types, const std::span<const std::string_view> 
dependent_properties,
-      const std::span<const std::pair<std::string_view, std::string_view>> 
exclusive_of_properties, std::optional<std::string_view> default_value,
+      const std::span<const std::string_view> allowed_values, std::span<const 
std::string_view> allowed_types, std::optional<std::string_view> default_value,
       const gsl::not_null<const PropertyValidator*> validator, const bool 
supports_expression_language)
       : name(name),
         display_name(display_name),
@@ -85,8 +78,6 @@ struct PropertyReference {
         is_sensitive(is_sensitive),
         allowed_values(allowed_values),
         allowed_types(allowed_types),
-        dependent_properties(dependent_properties),
-        exclusive_of_properties(exclusive_of_properties),
         default_value(default_value),
         validator(validator),
         supports_expression_language(supports_expression_language) {}

Reply via email to