Repository: nifi-minifi-cpp Updated Branches: refs/heads/master 906afb179 -> 54be9d403
MINIFICPP-501 Incorporate dependent property metadata into agent information MINIFICPP-502 Add validation to config parser to validate required properties This closes #334, closes #333. Signed-off-by: Marc Parisi <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/repo Commit: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/commit/54be9d40 Tree: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/tree/54be9d40 Diff: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/diff/54be9d40 Branch: refs/heads/master Commit: 54be9d403a0e588d27ebda9ea0b90ec558f970cb Parents: 906afb1 Author: Andrew I. Christianson <[email protected]> Authored: Mon May 21 11:55:14 2018 -0400 Committer: Marc Parisi <[email protected]> Committed: Thu May 24 13:38:01 2018 -0400 ---------------------------------------------------------------------- libminifi/include/core/Property.h | 9 ++- .../include/core/state/nodes/AgentInformation.h | 10 +++ libminifi/include/core/yaml/YamlConfiguration.h | 5 +- libminifi/src/core/ConfigurableComponent.cpp | 2 +- libminifi/src/core/Property.cpp | 6 ++ libminifi/src/core/yaml/YamlConfiguration.cpp | 72 ++++++++++++----- libminifi/src/processors/GetFile.cpp | 2 +- libminifi/src/processors/PutFile.cpp | 4 +- .../unit/PropertyValidationAgentInfoTests.cpp | 27 ++++++- libminifi/test/unit/YamlConfigurationTests.cpp | 81 ++++++++++++++++++++ 10 files changed, 191 insertions(+), 27 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/include/core/Property.h ---------------------------------------------------------------------- diff --git a/libminifi/include/core/Property.h b/libminifi/include/core/Property.h index 9aa19e5..9fb31fb 100644 --- a/libminifi/include/core/Property.h +++ b/libminifi/include/core/Property.h @@ -56,10 +56,15 @@ class Property { /*! * Create a new property */ - Property(const std::string name, const std::string description, const std::string value, bool is_required) + Property(const std::string name, + const std::string description, + const std::string value, + bool is_required, + std::vector<std::string> &&dependent_properties) : name_(name), description_(description), is_required_(is_required), + dependent_properties_(std::move(dependent_properties)), is_collection_(false) { values_.push_back(std::string(value.c_str())); } @@ -95,6 +100,7 @@ class Property { std::string getDescription() const; std::string getValue() const; bool getRequired() const; + std::vector<std::string> getDependentProperties() const; std::vector<std::string> &getValues(); // Set value for the property @@ -372,6 +378,7 @@ class Property { std::string name_; std::string description_; bool is_required_; + std::vector<std::string> dependent_properties_; bool is_collection_; std::vector<std::string> values_; http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/include/core/state/nodes/AgentInformation.h ---------------------------------------------------------------------- diff --git a/libminifi/include/core/state/nodes/AgentInformation.h b/libminifi/include/core/state/nodes/AgentInformation.h index c406610..b5b5df6 100644 --- a/libminifi/include/core/state/nodes/AgentInformation.h +++ b/libminifi/include/core/state/nodes/AgentInformation.h @@ -297,9 +297,19 @@ class ComponentManifest : public DeviceInformation { descriptorRequired.name = "required"; descriptorRequired.value = prop.second.getRequired(); + SerializedResponseNode descriptorDependentProperties; + descriptorDependentProperties.name = "dependentProperties"; + + for (const auto &propName : prop.second.getDependentProperties()) { + SerializedResponseNode descriptorDependentProperty; + descriptorDependentProperty.name = propName; + descriptorDependentProperties.children.push_back(descriptorDependentProperty); + } + child.children.push_back(descriptorName); child.children.push_back(descriptorDescription); child.children.push_back(descriptorRequired); + child.children.push_back(descriptorDependentProperties); props.children.push_back(child); } http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/include/core/yaml/YamlConfiguration.h ---------------------------------------------------------------------- diff --git a/libminifi/include/core/yaml/YamlConfiguration.h b/libminifi/include/core/yaml/YamlConfiguration.h index da71ba6..1d0a332 100644 --- a/libminifi/include/core/yaml/YamlConfiguration.h +++ b/libminifi/include/core/yaml/YamlConfiguration.h @@ -241,7 +241,10 @@ class YamlConfiguration : public FlowConfiguration { * @param propertiesNode the YAML::Node containing the properties * @param processor the Processor to which to add the resulting properties */ - void parsePropertiesNodeYaml(YAML::Node *propertiesNode, std::shared_ptr<core::ConfigurableComponent> processor); + void parsePropertiesNodeYaml(YAML::Node *propertiesNode, + std::shared_ptr<core::ConfigurableComponent> processor, + const std::string &component_name, + const std::string &yaml_section); /** * A helper function for parsing or generating optional id fields. http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/src/core/ConfigurableComponent.cpp ---------------------------------------------------------------------- diff --git a/libminifi/src/core/ConfigurableComponent.cpp b/libminifi/src/core/ConfigurableComponent.cpp index b81c20d..2b89acc 100644 --- a/libminifi/src/core/ConfigurableComponent.cpp +++ b/libminifi/src/core/ConfigurableComponent.cpp @@ -190,7 +190,7 @@ bool ConfigurableComponent::createDynamicProperty(const std::string &name, const return false; } - Property new_property(name, DEFAULT_DYNAMIC_PROPERTY_DESC, value, false); + Property new_property(name, DEFAULT_DYNAMIC_PROPERTY_DESC, value, false, {}); logger_->log_info("Processor %s dynamic property '%s' value '%s'", name.c_str(), new_property.getName().c_str(), value.c_str()); dynamic_properties_[new_property.getName()] = new_property; onDynamicPropertyModified({}, new_property); http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/src/core/Property.cpp ---------------------------------------------------------------------- diff --git a/libminifi/src/core/Property.cpp b/libminifi/src/core/Property.cpp index ebfcf0c..635dca5 100644 --- a/libminifi/src/core/Property.cpp +++ b/libminifi/src/core/Property.cpp @@ -71,9 +71,15 @@ const Property &Property::operator=(const Property &other) { values_ = other.values_; description_ = other.description_; is_collection_ = other.is_collection_; + is_required_ = other.is_required_; + dependent_properties_ = other.dependent_properties_; return *this; } +std::vector<std::string> Property::getDependentProperties() const { + return dependent_properties_; +} + } /* namespace core */ } /* namespace minifi */ } /* namespace nifi */ http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/src/core/yaml/YamlConfiguration.cpp ---------------------------------------------------------------------- diff --git a/libminifi/src/core/yaml/YamlConfiguration.cpp b/libminifi/src/core/yaml/YamlConfiguration.cpp index fbe84ed..54c5e07 100644 --- a/libminifi/src/core/yaml/YamlConfiguration.cpp +++ b/libminifi/src/core/yaml/YamlConfiguration.cpp @@ -17,7 +17,6 @@ */ #include <memory> -#include <string> #include <vector> #include <set> @@ -172,7 +171,7 @@ void YamlConfiguration::parseProcessorNodeYaml(YAML::Node processorsNode, core:: // handle processor properties if (procNode["Properties"]) { YAML::Node propertiesNode = procNode["Properties"]; - parsePropertiesNodeYaml(&propertiesNode, processor); + parsePropertiesNodeYaml(&propertiesNode, processor, procCfg.name, CONFIG_YAML_PROCESSORS_KEY); } // Take care of scheduling @@ -237,7 +236,7 @@ void YamlConfiguration::parseProcessorNodeYaml(YAML::Node processorsNode, core:: } } else { throw new std::invalid_argument("Cannot instantiate a MiNiFi instance without a defined " - "Processors configuration node."); + "Processors configuration node."); } } @@ -468,12 +467,16 @@ void YamlConfiguration::parseControllerServices(YAML::Node *controllerServicesNo logger_->log_debug("Created Controller Service with UUID %s and name %s", id, name); controller_service_node->initialize(); YAML::Node propertiesNode = controllerServiceNode["Properties"]; - // we should propogate propertiets to the node and to the implementation + // we should propogate properties to the node and to the implementation parsePropertiesNodeYaml(&propertiesNode, - std::static_pointer_cast<core::ConfigurableComponent>(controller_service_node)); + std::static_pointer_cast<core::ConfigurableComponent>(controller_service_node), + name, + CONFIG_YAML_CONTROLLER_SERVICES_KEY); if (controller_service_node->getControllerServiceImplementation() != nullptr) { parsePropertiesNodeYaml(&propertiesNode, - std::static_pointer_cast<core::ConfigurableComponent>(controller_service_node->getControllerServiceImplementation())); + std::static_pointer_cast<core::ConfigurableComponent>(controller_service_node->getControllerServiceImplementation()), + name, + CONFIG_YAML_CONTROLLER_SERVICES_KEY); } } controller_services_->put(id, controller_service_node); @@ -563,7 +566,7 @@ void YamlConfiguration::parseConnectionYaml(YAML::Node *connectionsNode, core::P std::string connectionSrcProcId = connectionNode["source id"].as<std::string>(); uuid_parse(connectionSrcProcId.c_str(), srcUUID); logger_->log_debug("Using 'source id' to match source with same id for " - "connection '%s': source id => [%s]", + "connection '%s': source id => [%s]", name, connectionSrcProcId); } else { // if we don't have a source id, try to resolve using source name. config schema v2 will make this unnecessary @@ -575,7 +578,7 @@ void YamlConfiguration::parseConnectionYaml(YAML::Node *connectionsNode, core::P // the source name is a remote port id, so use that as the source id uuid_copy(srcUUID, tmpUUID); logger_->log_debug("Using 'source name' containing a remote port id to match the source for " - "connection '%s': source name => [%s]", + "connection '%s': source name => [%s]", name, connectionSrcProcName); } else { // lastly, look the processor up by name @@ -583,7 +586,7 @@ void YamlConfiguration::parseConnectionYaml(YAML::Node *connectionsNode, core::P if (NULL != srcProcessor) { srcProcessor->getUUID(srcUUID); logger_->log_debug("Using 'source name' to match source with same name for " - "connection '%s': source name => [%s]", + "connection '%s': source name => [%s]", name, connectionSrcProcName); } else { // we ran out of ways to discover the source processor @@ -602,7 +605,7 @@ void YamlConfiguration::parseConnectionYaml(YAML::Node *connectionsNode, core::P std::string connectionDestProcId = connectionNode["destination id"].as<std::string>(); uuid_parse(connectionDestProcId.c_str(), destUUID); logger_->log_debug("Using 'destination id' to match destination with same id for " - "connection '%s': destination id => [%s]", + "connection '%s': destination id => [%s]", name, connectionDestProcId); } else { // we use the same logic as above for resolving the source processor @@ -616,7 +619,7 @@ void YamlConfiguration::parseConnectionYaml(YAML::Node *connectionsNode, core::P // the destination name is a remote port id, so use that as the dest id uuid_copy(destUUID, tmpUUID); logger_->log_debug("Using 'destination name' containing a remote port id to match the destination for " - "connection '%s': destination name => [%s]", + "connection '%s': destination name => [%s]", name, connectionDestProcName); } else { // look the processor up by name @@ -624,7 +627,7 @@ void YamlConfiguration::parseConnectionYaml(YAML::Node *connectionsNode, core::P if (NULL != destProcessor) { destProcessor->getUUID(destUUID); logger_->log_debug("Using 'destination name' to match destination with same name for " - "connection '%s': destination name => [%s]", + "connection '%s': destination name => [%s]", name, connectionDestProcName); } else { // we ran out of ways to discover the destination processor @@ -666,10 +669,10 @@ void YamlConfiguration::parsePortYaml(YAML::Node *portNode, checkRequiredField(&inputPortsObj, "id", CONFIG_YAML_REMOTE_PROCESS_GROUP_KEY, "The field 'id' is required for " - "the port named '" + nameStr + "' in the YAML Config. If this port " - "is an input port for a NiFi Remote Process Group, the port " - "id should match the corresponding id specified in the NiFi configuration. " - "This is a UUID of the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX."); + "the port named '" + nameStr + "' in the YAML Config. If this port " + "is an input port for a NiFi Remote Process Group, the port " + "id should match the corresponding id specified in the NiFi configuration. " + "This is a UUID of the format XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX."); auto portId = inputPortsObj["id"].as<std::string>(); uuid_parse(portId.c_str(), uuid); @@ -696,7 +699,10 @@ void YamlConfiguration::parsePortYaml(YAML::Node *portNode, // handle port properties YAML::Node nodeVal = portNode->as<YAML::Node>(); YAML::Node propertiesNode = nodeVal["Properties"]; - parsePropertiesNodeYaml(&propertiesNode, std::static_pointer_cast<core::ConfigurableComponent>(processor)); + parsePropertiesNodeYaml(&propertiesNode, + std::static_pointer_cast<core::ConfigurableComponent>(processor), + nameStr, + CONFIG_YAML_REMOTE_PROCESS_GROUP_KEY); // add processor to parent parent->addProcessor(processor); @@ -714,7 +720,9 @@ void YamlConfiguration::parsePortYaml(YAML::Node *portNode, } void YamlConfiguration::parsePropertiesNodeYaml(YAML::Node *propertiesNode, - std::shared_ptr<core::ConfigurableComponent> processor) { + std::shared_ptr<core::ConfigurableComponent> processor, + const std::string &component_name, + const std::string &yaml_section) { // Treat generically as a YAML node so we can perform inspection on entries to ensure they are populated for (YAML::const_iterator propsIter = propertiesNode->begin(); propsIter != propertiesNode->end(); ++propsIter) { std::string propertyName = propsIter->first.as<std::string>(); @@ -732,7 +740,7 @@ void YamlConfiguration::parsePropertiesNodeYaml(YAML::Node *propertiesNode, std::shared_ptr<core::Connectable> proc = std::dynamic_pointer_cast<core::Connectable>(processor); if (proc != 0) { logger_->log_warn("Received property %s with value %s but is not one of the properties for %s. " - "Attempting to add as dynamic property.", + "Attempting to add as dynamic property.", propertyName, rawValueString, proc->getName()); @@ -755,7 +763,7 @@ void YamlConfiguration::parsePropertiesNodeYaml(YAML::Node *propertiesNode, std::shared_ptr<core::Connectable> proc = std::dynamic_pointer_cast<core::Connectable>(processor); if (proc != 0) { logger_->log_warn("Received property %s with value %s but is not one of the properties for %s. " - "Attempting to add as dynamic property.", + "Attempting to add as dynamic property.", propertyName, rawValueString, proc->getName()); @@ -773,6 +781,28 @@ void YamlConfiguration::parsePropertiesNodeYaml(YAML::Node *propertiesNode, } } } + + // Validate required properties + for (const auto &prop_pair : processor->getProperties()) { + if (prop_pair.second.getRequired()) { + const auto &val = prop_pair.second.getValue(); + + if (val.empty()) { + // Build a helpful error message for the user so they can fix the + // invalid YAML config file, using the component name if present + std::string err_msg = + "Unable to parse configuration file for component named '" + + component_name + + "' because required property '" + prop_pair.second.getName() + "' is not set"; + if (!yaml_section.empty()) { + err_msg += " [in '" + yaml_section + "' section of configuration file]"; + } + logging::LOG_ERROR(logger_) << err_msg; + + throw std::invalid_argument(err_msg); + } + } + } } std::string YamlConfiguration::getOrGenerateId(YAML::Node *yamlNode, const std::string &idField) { @@ -784,7 +814,7 @@ std::string YamlConfiguration::getOrGenerateId(YAML::Node *yamlNode, const std:: id = node[idField].as<std::string>(); } else { throw std::invalid_argument("getOrGenerateId: idField is expected to reference YAML::Node " - "of YAML::NodeType::Scalar."); + "of YAML::NodeType::Scalar."); } } else { uuid_t uuid; http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/src/processors/GetFile.cpp ---------------------------------------------------------------------- diff --git a/libminifi/src/processors/GetFile.cpp b/libminifi/src/processors/GetFile.cpp index 22a2b73..63b722e 100644 --- a/libminifi/src/processors/GetFile.cpp +++ b/libminifi/src/processors/GetFile.cpp @@ -45,7 +45,7 @@ namespace minifi { namespace processors { core::Property GetFile::BatchSize("Batch Size", "The maximum number of files to pull in each iteration", "10"); -core::Property GetFile::Directory("Input Directory", "The input directory from which to pull files", "."); +core::Property GetFile::Directory("Input Directory", "The input directory from which to pull files", ".", true, {}); core::Property GetFile::IgnoreHiddenFile("Ignore Hidden Files", "Indicates whether or not hidden files should be ignored", "true"); core::Property GetFile::KeepSourceFile("Keep Source File", "If true, the file is not deleted after it has been copied to the Content Repository", "false"); core::Property GetFile::MaxAge("Maximum File Age", "The minimum age that a file must be in order to be pulled;" http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/src/processors/PutFile.cpp ---------------------------------------------------------------------- diff --git a/libminifi/src/processors/PutFile.cpp b/libminifi/src/processors/PutFile.cpp index f073025..99bf998 100644 --- a/libminifi/src/processors/PutFile.cpp +++ b/libminifi/src/processors/PutFile.cpp @@ -51,7 +51,9 @@ core::Property PutFile::CreateDirs( "Create Missing Directories", "If true, then missing destination directories will be created. " "If false, flowfiles are penalized and sent to failure.", - "true"); + "true", + true, + {"Directory"}); core::Property PutFile::MaxDestFiles( "Maximum File Count", "Specifies the maximum number of files that can exist in the output directory", http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp ---------------------------------------------------------------------- diff --git a/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp b/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp index 149e4e9..a7b297d 100644 --- a/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp +++ b/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp @@ -25,7 +25,7 @@ #include "core/Processor.h" #include "core/ClassLoader.h" -TEST_CASE("TestRequired", "[required]") { +TEST_CASE("Test Required", "[required]") { minifi::state::response::ComponentManifest manifest("PutFile"); auto serialized = manifest.serialize(); REQUIRE(serialized.size() > 0); @@ -43,3 +43,28 @@ TEST_CASE("TestRequired", "[required]") { REQUIRE("required" == prop_0_required.name); REQUIRE(!std::dynamic_pointer_cast<minifi::state::response::BoolValue>(prop_0_required.value.getValue())->getValue()); } + +TEST_CASE("Test Dependent", "[dependent]") { + minifi::state::response::ComponentManifest manifest("manifest"); + auto serialized = manifest.serialize(); + REQUIRE(serialized.size() > 0); + const auto &resp = serialized[0]; + REQUIRE(resp.children.size() > 0); + const auto &processors = resp.children[0]; + REQUIRE(processors.children.size() > 0); + minifi::state::response::SerializedResponseNode proc_0; + for (const auto &node : processors.children) { + if ("org::apache::nifi::minifi::processors::PutFile" == node.name) { + proc_0 = node; + } + } + REQUIRE(proc_0.children.size() > 0); + const auto &prop_descriptors = proc_0.children[0]; + REQUIRE(prop_descriptors.children.size() > 0); + const auto &prop_0 = prop_descriptors.children[1]; + REQUIRE(prop_0.children.size() >= 3); + const auto &prop_0_dependent = prop_0.children[3]; + REQUIRE("dependentProperties" == prop_0_dependent.name); + const auto &prop_0_dependent_0 = prop_0_dependent.children[0]; + REQUIRE("Directory" == prop_0_dependent_0.name); +} http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/54be9d40/libminifi/test/unit/YamlConfigurationTests.cpp ---------------------------------------------------------------------- diff --git a/libminifi/test/unit/YamlConfigurationTests.cpp b/libminifi/test/unit/YamlConfigurationTests.cpp index 0b853a6..724fc64 100644 --- a/libminifi/test/unit/YamlConfigurationTests.cpp +++ b/libminifi/test/unit/YamlConfigurationTests.cpp @@ -376,3 +376,84 @@ Processors: REQUIRE(LogTestController::getInstance().contains("[warning] Unable to set the dynamic property " "Dynamic Property with value Bad")); } + + +TEST_CASE("Test Required Property", "[YamlConfigurationRequiredProperty]") { + TestController test_controller; + + LogTestController &logTestController = LogTestController::getInstance(); + logTestController.setDebug<TestPlan>(); + logTestController.setDebug<core::YamlConfiguration>(); + + std::shared_ptr<core::Repository> testProvRepo = core::createRepository("provenancerepository", true); + std::shared_ptr<core::Repository> testFlowFileRepo = core::createRepository("flowfilerepository", true); + std::shared_ptr<minifi::Configure> configuration = std::make_shared<minifi::Configure>(); + std::shared_ptr<minifi::io::StreamFactory> streamFactory = std::make_shared<minifi::io::StreamFactory>(configuration); + std::shared_ptr<core::ContentRepository> + content_repo = std::make_shared<core::repository::VolatileContentRepository>(); + core::YamlConfiguration *yamlConfig = + new core::YamlConfiguration(testProvRepo, testFlowFileRepo, content_repo, streamFactory, configuration); + + static const std::string TEST_CONFIG_YAML = R"( +Flow Controller: + name: Simple +Processors: +- name: XYZ + class: GetFile + Properties: + Input Directory: "" + Batch Size: 1 + )"; + std::istringstream configYamlStream(TEST_CONFIG_YAML); + bool caught_exception = false; + + try { + std::unique_ptr<core::ProcessGroup> rootFlowConfig = yamlConfig->getYamlRoot(configYamlStream); + + REQUIRE(rootFlowConfig); + REQUIRE(rootFlowConfig->findProcessor("GetFile")); + REQUIRE(NULL != rootFlowConfig->findProcessor("GetFile")->getUUID()); + REQUIRE(!rootFlowConfig->findProcessor("GetFile")->getUUIDStr().empty()); + } catch (const std::exception &e) { + caught_exception = true; + REQUIRE("Unable to parse configuration file for component named 'XYZ' because required property " + "'Input Directory' is not set [in 'Processors' section of configuration file]" == std::string(e.what())); + } + + REQUIRE(caught_exception); +} + +TEST_CASE("Test Required Property 2", "[YamlConfigurationRequiredProperty2]") { + TestController test_controller; + + LogTestController &logTestController = LogTestController::getInstance(); + logTestController.setDebug<TestPlan>(); + logTestController.setDebug<core::YamlConfiguration>(); + + std::shared_ptr<core::Repository> testProvRepo = core::createRepository("provenancerepository", true); + std::shared_ptr<core::Repository> testFlowFileRepo = core::createRepository("flowfilerepository", true); + std::shared_ptr<minifi::Configure> configuration = std::make_shared<minifi::Configure>(); + std::shared_ptr<minifi::io::StreamFactory> streamFactory = std::make_shared<minifi::io::StreamFactory>(configuration); + std::shared_ptr<core::ContentRepository> + content_repo = std::make_shared<core::repository::VolatileContentRepository>(); + core::YamlConfiguration *yamlConfig = + new core::YamlConfiguration(testProvRepo, testFlowFileRepo, content_repo, streamFactory, configuration); + + static const std::string TEST_CONFIG_YAML = R"( +Flow Controller: + name: Simple +Processors: +- name: XYZ + class: GetFile + Properties: + Input Directory: "/" + Batch Size: 1 + )"; + std::istringstream configYamlStream(TEST_CONFIG_YAML); + std::unique_ptr<core::ProcessGroup> rootFlowConfig = yamlConfig->getYamlRoot(configYamlStream); + + REQUIRE(rootFlowConfig); + REQUIRE(rootFlowConfig->findProcessor("XYZ")); + REQUIRE(NULL != rootFlowConfig->findProcessor("XYZ")->getUUID()); + REQUIRE(!rootFlowConfig->findProcessor("XYZ")->getUUIDStr().empty()); +}
