You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by al...@apache.org on 2018/08/28 17:01:27 UTC

[1/2] nifi-minifi-cpp git commit: MINIFICPP-598: Add relationship support into manifest MINIFICPP-600: Add default value into property descriptors

Repository: nifi-minifi-cpp
Updated Branches:
  refs/heads/master 6084f71a9 -> 2ecb997c7


MINIFICPP-598: Add relationship support into manifest
MINIFICPP-600: Add default value into property descriptors


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/7ac309ba
Tree: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/tree/7ac309ba
Diff: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/diff/7ac309ba

Branch: refs/heads/master
Commit: 7ac309ba76813e5dbdb1e1857da4c6115a4c2fd1
Parents: 6084f71
Author: Marc Parisi <ph...@apache.org>
Authored: Mon Aug 20 12:26:14 2018 -0400
Committer: Marc Parisi <ph...@apache.org>
Committed: Tue Aug 21 15:26:41 2018 -0400

----------------------------------------------------------------------
 CMakeLists.txt                                  |   5 +-
 extensions/http-curl/processors/InvokeHTTP.cpp  |  23 ++--
 libminifi/include/agent/build_description.h     |  26 ++++-
 libminifi/include/core/ClassLoader.h            |  52 ++++++---
 libminifi/include/core/ConfigurableComponent.h  |   9 ++
 libminifi/include/core/Connectable.h            |   2 +
 libminifi/include/core/Property.h               | 116 ++++++++++++++++---
 libminifi/include/core/Relationship.h           |  12 ++
 libminifi/include/core/Resource.h               |   6 +-
 libminifi/include/core/state/Value.h            |   6 +-
 .../include/core/state/nodes/AgentInformation.h |  75 +++++++++++-
 libminifi/include/processors/RouteOnAttribute.h |   5 +
 libminifi/src/core/Connectable.cpp              |  10 +-
 libminifi/src/core/Property.cpp                 |  10 ++
 .../unit/PropertyValidationAgentInfoTests.cpp   |  40 ++++++-
 15 files changed, 327 insertions(+), 70 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3c33509..728042e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -412,11 +412,10 @@ endif()
 
 get_property(selected_extensions GLOBAL PROPERTY EXTENSION-OPTIONS)
 
+# Generate the build identifier if one is not provided
 if (NOT BUILD_IDENTIFIER)
-   if (NOT BUILD_IDENTIFIER)
      string(RANDOM LENGTH 24 BUILD_IDENTIFIER)
-     set(BUILD_IDENTIFIER "${BUILD_IDENTIFIER}" CACHE STRING "Build identifier")
-   endif()
+     set(BUILD_IDENTIFIER "${BUILD_IDENTIFIER}" CACHE STRING "Build identifier" FORCE)
 endif()
 
 message("BUILD_IDENTIFIER is ${BUILD_IDENTIFIER}")

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/extensions/http-curl/processors/InvokeHTTP.cpp
----------------------------------------------------------------------
diff --git a/extensions/http-curl/processors/InvokeHTTP.cpp b/extensions/http-curl/processors/InvokeHTTP.cpp
index 7ad5aef..9cff5aa 100644
--- a/extensions/http-curl/processors/InvokeHTTP.cpp
+++ b/extensions/http-curl/processors/InvokeHTTP.cpp
@@ -65,18 +65,15 @@ core::Property InvokeHTTP::FollowRedirects("Follow Redirects", "Follow HTTP redi
 core::Property InvokeHTTP::AttributesToSend("Attributes to Send", "Regular expression that defines which attributes to send as HTTP"
                                             " headers in the request. If not defined, no attributes are sent as headers.",
                                             "");
-core::Property InvokeHTTP::SSLContext("SSL Context Service",
-                                      "The SSL Context Service used to provide client certificate "
-                                      "information for TLS/SSL (https) connections.",
-                                      "",
-                                      false,
-                                      "",
-                                      {},
-                                      {{"Remote URL", "^http:.*$"}});
+core::Property InvokeHTTP::SSLContext(
+    core::PropertyBuilder::createProperty("SSL Context Service")->withDescription("The SSL Context Service used to provide client certificate "
+                                                                                  "information for TLS/SSL (https) connections.")->isRequired(false)->withExclusiveProperty("Remote URL", "^http:.*$")
+        ->asType<minifi::controllers::SSLContextService>()->build());
 core::Property InvokeHTTP::ProxyHost("Proxy Host", "The fully qualified hostname or IP address of the proxy server", "");
 core::Property InvokeHTTP::ProxyPort("Proxy Port", "The port of the proxy server", "");
 core::Property InvokeHTTP::ProxyUser("invokehttp-proxy-user", "Username to set when authenticating against proxy", "");
-core::Property InvokeHTTP::ProxyPassword("invokehttp-proxy-password", "Password to set when authenticating against proxy", "");
+core::Property InvokeHTTP::ProxyPassword(
+    core::PropertyBuilder::createProperty("invokehttp-proxy-password", "Proxy Password")->withDescription("Password to set when authenticating against proxy")->isRequired(false)->build());
 core::Property InvokeHTTP::ContentType("Content-type", "The Content-Type to specify for when content is being transmitted through a PUT, "
                                        "POST or PATCH. In the case of an empty value after evaluating an expression language expression, "
                                        "Content-Type defaults to",
@@ -366,12 +363,8 @@ void InvokeHTTP::onTrigger(const std::shared_ptr<core::ProcessContext> &context,
   }
 }
 
-void InvokeHTTP::route(std::shared_ptr<FlowFileRecord> &request,
-                       std::shared_ptr<FlowFileRecord> &response,
-                       const std::shared_ptr<core::ProcessSession> &session,
-                       const std::shared_ptr<core::ProcessContext> &context,
-                       bool isSuccess,
-                       int statusCode) {
+void InvokeHTTP::route(std::shared_ptr<FlowFileRecord> &request, std::shared_ptr<FlowFileRecord> &response, const std::shared_ptr<core::ProcessSession> &session,
+                       const std::shared_ptr<core::ProcessContext> &context, bool isSuccess, int statusCode) {
   // check if we should yield the processor
   if (!isSuccess && request == nullptr) {
     context->yield();

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/include/agent/build_description.h
----------------------------------------------------------------------
diff --git a/libminifi/include/agent/build_description.h b/libminifi/include/agent/build_description.h
index aa4b9e0..e02911c 100644
--- a/libminifi/include/agent/build_description.h
+++ b/libminifi/include/agent/build_description.h
@@ -29,17 +29,28 @@ namespace minifi {
 struct ClassDescription {
   explicit ClassDescription(std::string name)
       : class_name_(name),
-        support_dynamic_(false) {
+        dynamic_properties_(false),
+        dynamic_relationships_(false) {
   }
-  explicit ClassDescription(std::string name, std::map<std::string, core::Property> props, bool dyn)
+  explicit ClassDescription(std::string name, std::map<std::string, core::Property> props, bool dyn_prop)
       : class_name_(name),
         class_properties_(props),
-        support_dynamic_(dyn) {
+        dynamic_properties_(dyn_prop),
+        dynamic_relationships_(false) {
 
   }
+  explicit ClassDescription(std::string name, std::map<std::string, core::Property> props, std::vector<core::Relationship> class_relationships, bool dyn_prop, bool dyn_rel)
+      : class_name_(name),
+        class_properties_(props),
+        class_relationships_(class_relationships),
+        dynamic_properties_(dyn_prop),
+        dynamic_relationships_(dyn_rel) {
+  }
   std::string class_name_;
   std::map<std::string, core::Property> class_properties_;
-  bool support_dynamic_;
+  std::vector<core::Relationship> class_relationships_;
+  bool dynamic_properties_;
+  bool dynamic_relationships_;
 };
 
 struct Components {
@@ -69,13 +80,16 @@ class BuildDescription {
         ClassDescription description(clazz);
         if (nullptr != component) {
 
-          bool is_processor = std::dynamic_pointer_cast<core::Processor>(obj) != nullptr;
+          auto processor = std::dynamic_pointer_cast<core::Processor>(obj) ;
+          bool is_processor = processor != nullptr;
           bool is_controller_service = LIKELY(is_processor == true) ? false : std::dynamic_pointer_cast<core::controller::ControllerService>(obj) != nullptr;
 
           component->initialize();
           description.class_properties_ = component->getProperties();
-          description.support_dynamic_ = component->supportsDynamicProperties();
+          description.dynamic_properties_ = component->supportsDynamicProperties();
+          description.dynamic_relationships_ = component->supportsDynamicRelationships();
           if (is_processor) {
+            description.class_relationships_ = processor->getSupportedRelationships();
             class_mappings[group].processors_.emplace_back(description);
           } else if (is_controller_service) {
             class_mappings[group].controller_services_.emplace_back(description);

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/include/core/ClassLoader.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/ClassLoader.h b/libminifi/include/core/ClassLoader.h
index b1ecaf8..cc8d322 100644
--- a/libminifi/include/core/ClassLoader.h
+++ b/libminifi/include/core/ClassLoader.h
@@ -43,6 +43,14 @@ namespace core {
 class ObjectFactory {
 
  public:
+
+  ObjectFactory(const std::string &group)
+      : group_(group) {
+  }
+
+  ObjectFactory() {
+  }
+
   /**
    * Virtual destructor.
    */
@@ -84,6 +92,10 @@ class ObjectFactory {
    */
   virtual std::string getName() = 0;
 
+  virtual std::string getGroupName() const {
+    return group_;
+  }
+
   virtual std::string getClassName() = 0;
   /**
    * Gets the class name for the object
@@ -93,6 +105,10 @@ class ObjectFactory {
 
   virtual std::unique_ptr<ObjectFactory> assign(const std::string &class_name) = 0;
 
+ private:
+
+  std::string group_;
+
 };
 
 /**
@@ -107,6 +123,11 @@ class DefautObjectFactory : public ObjectFactory {
   DefautObjectFactory() {
     className = core::getClassName<T>();
   }
+
+  DefautObjectFactory(const std::string &group_name)
+      : ObjectFactory(group_name) {
+    className = core::getClassName<T>();
+  }
   /**
    * Virtual destructor.
    */
@@ -223,21 +244,14 @@ class ClassLoader {
 
     std::lock_guard<std::mutex> lock(internal_mutex_);
 
-    loaded_factories_.insert(std::make_pair(name, std::move(factory)));
-
-  }
-
-  /**
-   * Register a class with the give ProcessorFactory
-   */
-  void registerClass(const std::string &group, const std::string &name, std::unique_ptr<ObjectFactory> factory) {
-    if (loaded_factories_.find(name) != loaded_factories_.end()) {
-      return;
-    }
+    auto canonical_name = factory->getClassName();
 
-    std::lock_guard<std::mutex> lock(internal_mutex_);
+    auto group_name = factory->getGroupName();
 
-    module_mapping_[group].push_back(factory->getName());
+    module_mapping_[group_name].push_back(canonical_name);
+    if (canonical_name != name)
+      class_to_group_[canonical_name] = group_name;
+    class_to_group_[name] = group_name;
 
     loaded_factories_.insert(std::make_pair(name, std::move(factory)));
   }
@@ -269,6 +283,16 @@ class ClassLoader {
     return groups;
   }
 
+  std::string getGroupForClass(const std::string &class_name) {
+    std::lock_guard<std::mutex> lock(internal_mutex_);
+    auto factory_entry = class_to_group_.find(class_name);
+    if (factory_entry != class_to_group_.end()) {
+      return factory_entry->second;
+    } else {
+      return "";
+    }
+  }
+
   /**
    * Instantiate object based on class_name
    * @param class_name class to create
@@ -311,6 +335,8 @@ class ClassLoader {
 
   std::map<std::string, std::unique_ptr<ObjectFactory>> loaded_factories_;
 
+  std::map<std::string, std::string> class_to_group_;
+
   std::mutex internal_mutex_;
 
   std::vector<void *> dl_handles_;

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/include/core/ConfigurableComponent.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/ConfigurableComponent.h b/libminifi/include/core/ConfigurableComponent.h
index d69e1c7..53835b4 100644
--- a/libminifi/include/core/ConfigurableComponent.h
+++ b/libminifi/include/core/ConfigurableComponent.h
@@ -100,6 +100,15 @@ class __attribute__((visibility("default"))) ConfigurableComponent {
   virtual bool supportsDynamicProperties() = 0;
 
   /**
+   * Gets whether or not this processor supports dynamic relationships.
+   *
+   * @return true if this component supports dynamic relationships (default is false)
+   */
+  virtual bool supportsDynamicRelationships() {
+    return false;
+  }
+
+  /**
    * Gets the value of a dynamic property (if it was set).
    *
    * @param name

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/include/core/Connectable.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/Connectable.h b/libminifi/include/core/Connectable.h
index ec2fd3a..1c1fd45 100644
--- a/libminifi/include/core/Connectable.h
+++ b/libminifi/include/core/Connectable.h
@@ -49,6 +49,8 @@ class __attribute__((visibility("default"))) Connectable : public CoreComponent
   // Whether the relationship is supported
   bool isSupportedRelationship(Relationship relationship);
 
+  std::vector<Relationship> getSupportedRelationships() const;
+
   /**
    * Sets auto terminated relationships
    * @param relationships

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/include/core/Property.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/Property.h b/libminifi/include/core/Property.h
index a59a53d..1b1b587 100644
--- a/libminifi/include/core/Property.h
+++ b/libminifi/include/core/Property.h
@@ -19,11 +19,13 @@
 #define __PROPERTY_H__
 
 #include <algorithm>
+#include "core/Core.h"
 #include <sstream>
 #include <string>
 #include <vector>
 #include <queue>
 #include <map>
+#include <memory>
 #include <mutex>
 #include <atomic>
 #include <functional>
@@ -47,18 +49,15 @@ enum TimeUnit {
   NANOSECOND
 };
 
+class PropertyBuilder;
+
 class Property {
 
  public:
   /*!
    * Create a new property
    */
-  Property(std::string name,
-           std::string description,
-           std::string value,
-           bool is_required,
-           std::string valid_regex,
-           std::vector<std::string> dependent_properties,
+  Property(std::string name, std::string description, std::string value, bool is_required, std::string valid_regex, std::vector<std::string> dependent_properties,
            std::vector<std::pair<std::string, std::string>> exclusive_of_properties)
       : name_(std::move(name)),
         description_(std::move(description)),
@@ -85,6 +84,32 @@ class Property {
         is_collection_(true) {
   }
 
+  Property(Property &&other)
+      : name_(std::move(other.name_)),
+        description_(std::move(other.description_)),
+        is_required_(other.is_required_),
+        valid_regex_(std::move(other.valid_regex_)),
+        dependent_properties_(std::move(other.dependent_properties_)),
+        exclusive_of_properties_(std::move(other.exclusive_of_properties_)),
+        is_collection_(other.is_collection_),
+        values_(std::move(other.values_)),
+        display_name_(std::move(other.display_name_)),
+        types_(std::move(other.types_)){
+  }
+
+  Property(const Property &other)
+      : name_(other.name_),
+        description_(other.description_),
+        is_required_(other.is_required_),
+        valid_regex_(other.valid_regex_),
+        dependent_properties_(other.dependent_properties_),
+        exclusive_of_properties_(other.exclusive_of_properties_),
+        is_collection_(other.is_collection_),
+        values_(other.values_),
+        display_name_(other.display_name_),
+        types_(other.types_){
+  }
+
   Property()
       : name_(""),
         description_(""),
@@ -95,6 +120,8 @@ class Property {
   virtual ~Property() = default;
 
   std::string getName() const;
+  std::string getDisplayName() const;
+  std::vector<std::string> getAllowedTypes() const;
   std::string getDescription() const;
   std::string getValue() const;
   bool getRequired() const;
@@ -109,10 +136,10 @@ class Property {
    */
   void addValue(std::string value);
   const Property &operator=(const Property &other);
-  // Compare
+// Compare
   bool operator <(const Property & right) const;
 
-  // Convert TimeUnit to MilliSecond
+// Convert TimeUnit to MilliSecond
   template<typename T>
   static bool ConvertTimeUnitToMS(int64_t input, TimeUnit unit, T &out) {
     if (unit == MILLISECOND) {
@@ -146,7 +173,7 @@ class Property {
     return ConvertTimeUnitToMS<uint64_t>(input, unit, out);
   }
 
-  // Convert TimeUnit to NanoSecond
+// Convert TimeUnit to NanoSecond
   template<typename T>
   static bool ConvertTimeUnitToNS(int64_t input, TimeUnit unit, T &out) {
     if (unit == MILLISECOND) {
@@ -169,17 +196,17 @@ class Property {
     }
   }
 
-  // Convert TimeUnit to NanoSecond
+// Convert TimeUnit to NanoSecond
   static bool ConvertTimeUnitToNS(int64_t input, TimeUnit unit, uint64_t &out) {
     return ConvertTimeUnitToNS<uint64_t>(input, unit, out);
   }
 
-  // Convert TimeUnit to NanoSecond
+// Convert TimeUnit to NanoSecond
   static bool ConvertTimeUnitToNS(int64_t input, TimeUnit unit, int64_t &out) {
     return ConvertTimeUnitToNS<int64_t>(input, unit, out);
   }
 
-  // Convert String
+// Convert String
   static bool StringToTime(std::string input, uint64_t &output, TimeUnit &timeunit) {
     if (input.size() == 0) {
       return false;
@@ -233,7 +260,7 @@ class Property {
       return false;
   }
 
-  // Convert String
+// Convert String
   static bool StringToTime(std::string input, int64_t &output, TimeUnit &timeunit) {
     if (input.size() == 0) {
       return false;
@@ -287,7 +314,7 @@ class Property {
       return false;
   }
 
-  // Convert String to Integer
+// Convert String to Integer
   template<typename T>
   static bool StringToInt(std::string input, T &output) {
     if (input.size() == 0) {
@@ -359,7 +386,7 @@ class Property {
     return StringToInt<int64_t>(input, output);
   }
 
-  // Convert String to Integer
+// Convert String to Integer
   static bool StringToInt(std::string input, uint64_t &output) {
     return StringToInt<uint64_t>(input, output);
   }
@@ -368,12 +395,13 @@ class Property {
     return StringToInt<int32_t>(input, output);
   }
 
-  // Convert String to Integer
+// Convert String to Integer
   static bool StringToInt(std::string input, uint32_t &output) {
     return StringToInt<uint32_t>(input, output);
   }
 
  protected:
+
   std::string name_;
   std::string description_;
   bool is_required_;
@@ -382,11 +410,65 @@ class Property {
   std::vector<std::pair<std::string, std::string>> exclusive_of_properties_;
   bool is_collection_;
   std::vector<std::string> values_;
-
+  std::string display_name_;
+  // types represents the allowable types for this property
+  // these types should be the canonical name.
+  std::vector<std::string> types_;
  private:
 
+  friend class PropertyBuilder;
 };
 
+class PropertyBuilder : public std::enable_shared_from_this<PropertyBuilder> {
+ public:
+  static std::shared_ptr<PropertyBuilder> createProperty(const std::string &name) {
+    std::shared_ptr<PropertyBuilder> builder = std::unique_ptr<PropertyBuilder>(new PropertyBuilder());
+    builder->prop.name_ = name;
+    return builder;
+  }
+
+  static std::shared_ptr<PropertyBuilder> createProperty(const std::string &name, const std::string &displayName) {
+    std::shared_ptr<PropertyBuilder> builder = std::unique_ptr<PropertyBuilder>(new PropertyBuilder());
+    builder->prop.name_ = name;
+    builder->prop.display_name_ = displayName;
+    return builder;
+  }
+
+  std::shared_ptr<PropertyBuilder> withDescription(const std::string &description) {
+    prop.description_ = description;
+    return shared_from_this();
+  }
+
+  std::shared_ptr<PropertyBuilder> isRequired(bool required) {
+    prop.is_required_ = false;
+    return shared_from_this();
+  }
+
+  std::shared_ptr<PropertyBuilder> withDefaultValue(const std::string &df) {
+    prop.values_.push_back(std::move(df));
+    return shared_from_this();
+  }
+
+  template<typename T>
+  std::shared_ptr<PropertyBuilder> asType() {
+    prop.types_.push_back(core::getClassName<T>());
+    return shared_from_this();
+  }
+
+  std::shared_ptr<PropertyBuilder> withExclusiveProperty(const std::string &property, const std::string regex) {
+    prop.exclusive_of_properties_.push_back( { property, regex });
+    return shared_from_this();
+  }
+
+  Property &&build() {
+    return std::move(prop);
+  }
+ private:
+  Property prop;
+
+  PropertyBuilder() {
+  }
+};
 } /* namespace core */
 } /* namespace minifi */
 } /* namespace nifi */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/include/core/Relationship.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/Relationship.h b/libminifi/include/core/Relationship.h
index d0157d9..f2c442a 100644
--- a/libminifi/include/core/Relationship.h
+++ b/libminifi/include/core/Relationship.h
@@ -55,6 +55,12 @@ class Relationship {
       : name_(name),
         description_(description) {
   }
+
+  Relationship(const Relationship &other)
+      : name_(other.name_),
+        description_(other.description_) {
+  }
+
   Relationship()
       : name_(UNDEFINED_RELATIONSHIP) {
   }
@@ -73,6 +79,12 @@ class Relationship {
   bool operator <(const Relationship & right) const {
     return name_ < right.name_;
   }
+
+  Relationship &operator=(const Relationship &other) {
+    name_ = other.name_;
+    description_ = other.description_;
+    return *this;
+  }
   // Whether it is a undefined relationship
   bool isRelationshipUndefined() {
     return isRelationshipNameUndefined(name_);

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/include/core/Resource.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/Resource.h b/libminifi/include/core/Resource.h
index 410b947..742d879 100644
--- a/libminifi/include/core/Resource.h
+++ b/libminifi/include/core/Resource.h
@@ -26,11 +26,9 @@ namespace nifi {
 namespace minifi {
 namespace core {
 
-
 #define MKSOC(x) #x
 #define MAKESTRING(x) MKSOC(x)
 
-
 template<class T>
 class StaticClassType {
  public:
@@ -38,9 +36,9 @@ class StaticClassType {
   StaticClassType(const std::string &name) {
     // Notify when the static member is created
 #ifdef MODULE_NAME
-    ClassLoader::getDefaultClassLoader().registerClass(MAKESTRING(MODULE_NAME), name, std::unique_ptr<ObjectFactory>(new DefautObjectFactory<T>()));
+    ClassLoader::getDefaultClassLoader().registerClass(name, std::unique_ptr<ObjectFactory>(new DefautObjectFactory<T>(MAKESTRING(MODULE_NAME))));
 #else
-    ClassLoader::getDefaultClassLoader().registerClass("minifi-system", name, std::unique_ptr<ObjectFactory>(new DefautObjectFactory<T>()));
+    ClassLoader::getDefaultClassLoader().registerClass(name, std::unique_ptr<ObjectFactory>(new DefautObjectFactory<T>("minifi-system")));
 #endif
   }
 };

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/include/core/state/Value.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/state/Value.h b/libminifi/include/core/state/Value.h
index f4a92ad..a80404c 100644
--- a/libminifi/include/core/state/Value.h
+++ b/libminifi/include/core/state/Value.h
@@ -46,6 +46,10 @@ class Value {
     return string_value;
   }
 
+  bool empty(){
+    return string_value.empty();
+  }
+
  protected:
   std::string string_value;
 
@@ -184,7 +188,7 @@ class ValueNode {
   }
 
   bool empty() const {
-    return value_ == nullptr;
+    return value_ == nullptr || value_->empty();
   }
 
  protected:

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/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 7b72908..baafbbe 100644
--- a/libminifi/include/core/state/nodes/AgentInformation.h
+++ b/libminifi/include/core/state/nodes/AgentInformation.h
@@ -58,7 +58,6 @@ namespace response {
 
 #define GROUP_STR "org::apache::nifi::minifi"
 
-
 class ComponentManifest : public DeviceInformation {
  public:
   ComponentManifest(std::string name, uuid_t uuid)
@@ -99,7 +98,6 @@ class ComponentManifest : public DeviceInformation {
         className.name = "type";
         className.value = group.class_name_;
 
-
         if (!group.class_properties_.empty()) {
           SerializedResponseNode props;
           props.name = "propertyDescriptors";
@@ -124,6 +122,10 @@ class ComponentManifest : public DeviceInformation {
             descriptorValidRegex.name = "validRegex";
             descriptorValidRegex.value = prop.second.getValidRegex();
 
+            SerializedResponseNode descriptorDefaultValue;
+            descriptorDefaultValue.name = "defaultValue";
+            descriptorDefaultValue.value = prop.second.getValue();
+
             SerializedResponseNode descriptorDependentProperties;
             descriptorDependentProperties.name = "dependentProperties";
 
@@ -143,9 +145,42 @@ class ComponentManifest : public DeviceInformation {
               descriptorExclusiveOfProperties.children.push_back(descriptorExclusiveOfProperty);
             }
 
+            const auto &allowed_types = prop.second.getAllowedTypes();
+            if (!allowed_types.empty()) {
+              SerializedResponseNode allowed_type;
+              allowed_type.name = "typeProvidedByValue";
+              for (const auto &type : allowed_types) {
+                SerializedResponseNode typeNode;
+                typeNode.name = "type";
+                typeNode.value = type;
+                allowed_type.children.push_back(typeNode);
+
+                SerializedResponseNode bgroup;
+                bgroup.name = "group";
+                bgroup.value = GROUP_STR;
+                SerializedResponseNode artifact;
+                artifact.name = "artifact";
+                artifact.value = core::ClassLoader::getDefaultClassLoader().getGroupForClass(type);
+                allowed_type.children.push_back(typeNode);
+                allowed_type.children.push_back(bgroup);
+                allowed_type.children.push_back(artifact);
+
+              }
+              child.children.push_back(allowed_type);
+
+            }
+
             child.children.push_back(descriptorName);
+
+            if (prop.first != prop.second.getDisplayName()) {
+              SerializedResponseNode displayName;
+              displayName.name = "displayName";
+              displayName.value = prop.second.getDisplayName();
+              child.children.push_back(displayName);
+            }
             child.children.push_back(descriptorDescription);
             child.children.push_back(descriptorRequired);
+            child.children.push_back(descriptorDefaultValue);
             child.children.push_back(descriptorValidRegex);
             child.children.push_back(descriptorDependentProperties);
             child.children.push_back(descriptorExclusiveOfProperties);
@@ -158,10 +193,39 @@ class ComponentManifest : public DeviceInformation {
 
         SerializedResponseNode dyn_prop;
         dyn_prop.name = "supportsDynamicProperties";
-        dyn_prop.value = group.support_dynamic_;
+        dyn_prop.value = group.dynamic_properties_;
+
+        SerializedResponseNode dyn_relat;
+        dyn_relat.name = "supportsDynamicRelationships";
+        dyn_relat.value = group.dynamic_relationships_;
 
+        if (group.class_relationships_.size() > 0) {
+          SerializedResponseNode relationships;
+          relationships.name = "supportedRelationships";
+          relationships.array = true;
+
+          for (const auto &relationship : group.class_relationships_) {
+            SerializedResponseNode child;
+            child.name = "supportedRelationships";
+
+            SerializedResponseNode nameNode;
+            nameNode.name = "name";
+            nameNode.value = relationship.getName();
+
+            SerializedResponseNode descriptorDescription;
+            descriptorDescription.name = "description";
+            descriptorDescription.value = relationship.getDescription();
+            child.children.push_back(nameNode);
+            child.children.push_back(descriptorDescription);
+
+            relationships.children.push_back(child);
+          }
+          desc.children.push_back(relationships);
+        }
+        desc.children.push_back(dyn_relat);
         desc.children.push_back(dyn_prop);
         desc.children.push_back(className);
+
         type.children.push_back(desc);
       }
       response.children.push_back(type);
@@ -170,7 +234,6 @@ class ComponentManifest : public DeviceInformation {
   }
 };
 
-
 class Bundles : public DeviceInformation {
  public:
   Bundles(std::string name, uuid_t uuid)
@@ -519,7 +582,7 @@ class AgentInformation : public DeviceInformation, public AgentMonitor, public A
 
         SerializedResponseNode dyn_prop;
         dyn_prop.name = "supportsDynamicProperties";
-        dyn_prop.value = group.support_dynamic_;
+        dyn_prop.value = group.dynamic_properties_;
 
         desc.children.push_back(dyn_prop);
 
@@ -554,7 +617,7 @@ class AgentInformation : public DeviceInformation, public AgentMonitor, public A
 
         SerializedResponseNode dyn_prop;
         dyn_prop.name = "supportsDynamicProperties";
-        dyn_prop.value = group.support_dynamic_;
+        dyn_prop.value = group.dynamic_properties_;
 
         desc.children.push_back(dyn_prop);
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/include/processors/RouteOnAttribute.h
----------------------------------------------------------------------
diff --git a/libminifi/include/processors/RouteOnAttribute.h b/libminifi/include/processors/RouteOnAttribute.h
index eac392e..1c1eb45 100644
--- a/libminifi/include/processors/RouteOnAttribute.h
+++ b/libminifi/include/processors/RouteOnAttribute.h
@@ -56,6 +56,11 @@ class RouteOnAttribute : public core::Processor {
     return true;
   };
 
+
+  virtual bool supportsDynamicRelationships() {
+    return true;
+  }
+
   virtual void onDynamicPropertyModified(const core::Property &orig_property,
                                          const core::Property &new_property);
   virtual void onTrigger(core::ProcessContext *context,

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/src/core/Connectable.cpp
----------------------------------------------------------------------
diff --git a/libminifi/src/core/Connectable.cpp b/libminifi/src/core/Connectable.cpp
index 746f5ec..2a98818 100644
--- a/libminifi/src/core/Connectable.cpp
+++ b/libminifi/src/core/Connectable.cpp
@@ -65,6 +65,14 @@ bool Connectable::setSupportedRelationships(std::set<core::Relationship> relatio
   return true;
 }
 
+std::vector<Relationship> Connectable::getSupportedRelationships() const {
+  std::vector<Relationship> relationships;
+  for (auto const &item : relationships_) {
+    relationships.push_back(item.second);
+  }
+  return relationships;
+}
+
 // Whether the relationship is supported
 bool Connectable::isSupportedRelationship(core::Relationship relationship) {
   // if we are running we do not need a lock since the function to change relationships_ ( setSupportedRelationships)
@@ -100,7 +108,7 @@ bool Connectable::setAutoTerminatedRelationships(std::set<Relationship> relation
 // Check whether the relationship is auto terminated
 bool Connectable::isAutoTerminated(core::Relationship relationship) {
   // if we are running we do not need a lock since the function to change relationships_ ( setSupportedRelationships)
-    // cannot be executed while we are running
+  // cannot be executed while we are running
   const bool isConnectableRunning = isRunning();
 
   const auto conditionalLock = isConnectableRunning ? std::unique_lock<std::mutex>() : std::unique_lock<std::mutex>(relationship_mutex_);

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/src/core/Property.cpp
----------------------------------------------------------------------
diff --git a/libminifi/src/core/Property.cpp b/libminifi/src/core/Property.cpp
index 4065dc7..bb84e44 100644
--- a/libminifi/src/core/Property.cpp
+++ b/libminifi/src/core/Property.cpp
@@ -27,10 +27,18 @@ std::string Property::getName() const {
   return name_;
 }
 
+std::string Property::getDisplayName() const {
+  return display_name_.empty() ? name_ : display_name_;
+}
+
 std::string Property::getDescription() const {
   return description_;
 }
 
+std::vector<std::string> Property::getAllowedTypes() const {
+  return types_;
+}
+
 std::string Property::getValue() const {
   if (!values_.empty())
     return values_.front();
@@ -69,6 +77,8 @@ bool Property::operator<(const Property &right) const {
 
 const Property &Property::operator=(const Property &other) {
   name_ = other.name_;
+  display_name_ = other.display_name_;
+  types_ = other.types_;
   values_ = other.values_;
   description_ = other.description_;
   is_collection_ = other.is_collection_;

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/7ac309ba/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp
----------------------------------------------------------------------
diff --git a/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp b/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp
index 7a393c5..31f9b7b 100644
--- a/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp
+++ b/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp
@@ -58,10 +58,42 @@ TEST_CASE("Test Valid Regex", "[validRegex]") {
   REQUIRE(prop_descriptors.children.size() > 0);
   const auto &prop_0 = prop_descriptors.children[0];
   REQUIRE(prop_0.children.size() >= 3);
-  const auto &prop_0_valid_regex = prop_0.children[3];
+  const auto &df = prop_0.children[3];
+  REQUIRE("defaultValue" == df.name);
+  const auto &prop_0_valid_regex = prop_0.children[4];
   REQUIRE("validRegex" == prop_0_valid_regex.name);
 }
 
+TEST_CASE("Test Relationships", "[rel1]") {
+  minifi::state::response::ComponentManifest manifest("minifi-system");
+  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 &relationships = proc_0.children[1];
+  REQUIRE("supportedRelationships" == relationships.name);
+  // this is because they are now nested
+  REQUIRE("supportedRelationships" ==  relationships.children[0].name);
+  REQUIRE("name" ==  relationships.children[0].children[0].name);
+  REQUIRE("failure" ==  relationships.children[0].children[0].value.to_string());
+  REQUIRE("description" ==  relationships.children[0].children[1].name);
+
+  REQUIRE("success" ==  relationships.children[1].children[0].value.to_string());
+  REQUIRE("description" ==  relationships.children[1].children[1].name);
+
+
+}
+
+
 TEST_CASE("Test Dependent", "[dependent]") {
   minifi::state::response::ComponentManifest manifest("minifi-system");
   auto serialized = manifest.serialize();
@@ -81,8 +113,8 @@ TEST_CASE("Test Dependent", "[dependent]") {
   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[4];
-  REQUIRE("dependentProperties" == prop_0_dependent.name);
-  const auto &prop_0_dependent_0 = prop_0_dependent.children[0];
+  REQUIRE("defaultValue" == prop_0.children[3].name);
+  REQUIRE("validRegex" == prop_0.children[4].name);
+  const auto &prop_0_dependent_0 = prop_descriptors.children[2];
   REQUIRE("Directory" == prop_0_dependent_0.name);
 }


[2/2] nifi-minifi-cpp git commit: MINIFICPP-601: Add scheduling information

Posted by al...@apache.org.
MINIFICPP-601: Add scheduling information

This closes #392.

Signed-off-by: Aldrin Piri <al...@apache.org>


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/2ecb997c
Tree: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/tree/2ecb997c
Diff: http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/diff/2ecb997c

Branch: refs/heads/master
Commit: 2ecb997c72a5b6d80fb73d1eaf67b1e30cbf5c31
Parents: 7ac309b
Author: Marc Parisi <ph...@apache.org>
Authored: Tue Aug 21 20:22:57 2018 -0400
Committer: Aldrin Piri <al...@apache.org>
Committed: Tue Aug 28 12:59:54 2018 -0400

----------------------------------------------------------------------
 libminifi/include/core/Processor.h              |   9 +-
 libminifi/include/core/ProcessorConfig.h        |   8 ++
 .../include/core/state/nodes/AgentInformation.h |  58 ++++++++
 libminifi/src/core/Processor.cpp                |   5 +-
 libminifi/src/core/yaml/YamlConfiguration.cpp   |   6 +-
 libminifi/test/unit/ManifestTests.cpp           | 143 +++++++++++++++++++
 .../unit/PropertyValidationAgentInfoTests.cpp   | 120 ----------------
 7 files changed, 218 insertions(+), 131 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/2ecb997c/libminifi/include/core/Processor.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/Processor.h b/libminifi/include/core/Processor.h
index 18fe2a0..6426f4c 100644
--- a/libminifi/include/core/Processor.h
+++ b/libminifi/include/core/Processor.h
@@ -53,9 +53,6 @@ namespace core {
 // Minimum scheduling period in Nano Second
 #define MINIMUM_SCHEDULING_NANOS 30000
 
-// Default yield period in second
-#define DEFAULT_YIELD_PERIOD_SECONDS 1
-
 // Default penalization period in second
 #define DEFAULT_PENALIZATION_PERIOD_SECONDS 30
 
@@ -107,11 +104,11 @@ class __attribute__((visibility("default"))) Processor : public Connectable, pub
   }
   // Set Processor Run Duration in Nano Second
   void setRunDurationNano(uint64_t period) {
-    run_durantion_nano_ = period;
+    run_duration_nano_ = period;
   }
   // Get Processor Run Duration in Nano Second
   uint64_t getRunDurationNano(void) {
-    return (run_durantion_nano_);
+    return (run_duration_nano_);
   }
   // Set Processor yield period in MilliSecond
   void setYieldPeriodMsec(uint64_t period) {
@@ -258,7 +255,7 @@ class __attribute__((visibility("default"))) Processor : public Connectable, pub
   // SchedulePeriod in Nano Seconds
   std::atomic<uint64_t> scheduling_period_nano_;
   // Run Duration in Nano Seconds
-  std::atomic<uint64_t> run_durantion_nano_;
+  std::atomic<uint64_t> run_duration_nano_;
   // Yield Period in Milliseconds
   std::atomic<uint64_t> yield_period_msec_;
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/2ecb997c/libminifi/include/core/ProcessorConfig.h
----------------------------------------------------------------------
diff --git a/libminifi/include/core/ProcessorConfig.h b/libminifi/include/core/ProcessorConfig.h
index c1d563e..aa8e18c 100644
--- a/libminifi/include/core/ProcessorConfig.h
+++ b/libminifi/include/core/ProcessorConfig.h
@@ -26,6 +26,14 @@ namespace nifi {
 namespace minifi {
 namespace core {
 
+
+#define DEFAULT_SCHEDULING_STRATEGY "TIMER_DRIVEN"
+#define DEFAULT_SCHEDULING_PERIOD "1 sec"
+#define DEFAULT_RUN_DURATION 0
+#define DEFAULT_MAX_CONCURRENT_TASKS 1
+// Default yield period in second
+#define DEFAULT_YIELD_PERIOD_SECONDS 1
+
 struct ProcessorConfig {
   std::string id;
   std::string name;

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/2ecb997c/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 baafbbe..48a451c 100644
--- a/libminifi/include/core/state/nodes/AgentInformation.h
+++ b/libminifi/include/core/state/nodes/AgentInformation.h
@@ -48,6 +48,7 @@
 #include "agent/build_description.h"
 #include "core/ClassLoader.h"
 #include "../nodes/StateMonitor.h"
+#include "core/ProcessorConfig.h"
 
 namespace org {
 namespace apache {
@@ -284,6 +285,57 @@ class Bundles : public DeviceInformation {
 
 };
 
+class SchedulingDefaults : public DeviceInformation {
+ public:
+  SchedulingDefaults(std::string name, uuid_t uuid)
+      : DeviceInformation(name, uuid) {
+  }
+
+  SchedulingDefaults(const std::string &name)
+      : DeviceInformation(name, 0) {
+  }
+
+  std::string getName() const {
+    return "schedulingDefaults";
+  }
+
+  std::vector<SerializedResponseNode> serialize() {
+    std::vector<SerializedResponseNode> serialized;
+
+    SerializedResponseNode schedulingDefaults;
+    schedulingDefaults.name = "schedulingDefaults";
+
+    SerializedResponseNode defaultSchedulingStrategy;
+    defaultSchedulingStrategy.name = "defaultSchedulingStrategy";
+    defaultSchedulingStrategy.value = DEFAULT_SCHEDULING_STRATEGY;
+
+    schedulingDefaults.children.push_back(defaultSchedulingStrategy);
+
+    SerializedResponseNode defaultSchedulingPeriod;
+    defaultSchedulingPeriod.name = "defaultSchedulingPeriod";
+    defaultSchedulingPeriod.value = DEFAULT_SCHEDULING_PERIOD;
+
+    schedulingDefaults.children.push_back(defaultSchedulingPeriod);
+
+    SerializedResponseNode defaultRunDuration;
+    defaultRunDuration.name = "defaultRunDurationNanos";
+    defaultRunDuration.value = DEFAULT_RUN_DURATION;
+
+    schedulingDefaults.children.push_back(defaultRunDuration);
+
+    SerializedResponseNode defaultMaxConcurrentTasks;
+    defaultMaxConcurrentTasks.name = "defaultMaxConcurrentTasks";
+    defaultMaxConcurrentTasks.value = DEFAULT_MAX_CONCURRENT_TASKS;
+
+    schedulingDefaults.children.push_back(defaultMaxConcurrentTasks);
+
+    serialized.push_back(schedulingDefaults);
+
+    return serialized;
+  }
+
+};
+
 /**
  * Justification and Purpose: Provides available extensions for the agent information block.
  */
@@ -491,6 +543,12 @@ class AgentManifest : public DeviceInformation {
       serialized.push_back(bundle);
     }
 
+    SchedulingDefaults defaults("schedulingDefaults", nullptr);
+
+    for (auto defaultNode : defaults.serialize()) {
+      serialized.push_back(defaultNode);
+    }
+
     return serialized;
   }
 };

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/2ecb997c/libminifi/src/core/Processor.cpp
----------------------------------------------------------------------
diff --git a/libminifi/src/core/Processor.cpp b/libminifi/src/core/Processor.cpp
index 7adf718..d49bd55 100644
--- a/libminifi/src/core/Processor.cpp
+++ b/libminifi/src/core/Processor.cpp
@@ -31,6 +31,7 @@
 #include <functional>
 #include <utility>
 #include "Connection.h"
+#include "core/ProcessorConfig.h"
 #include "core/Connectable.h"
 #include "core/ProcessContext.h"
 #include "core/ProcessSession.h"
@@ -55,10 +56,10 @@ Processor::Processor(std::string name, uuid_t uuid)
   loss_tolerant_ = false;
   _triggerWhenEmpty = false;
   scheduling_period_nano_ = MINIMUM_SCHEDULING_NANOS;
-  run_durantion_nano_ = 0;
+  run_duration_nano_ = DEFAULT_RUN_DURATION;
   yield_period_msec_ = DEFAULT_YIELD_PERIOD_SECONDS * 1000;
   _penalizationPeriodMsec = DEFAULT_PENALIZATION_PERIOD_SECONDS * 1000;
-  max_concurrent_tasks_ = 1;
+  max_concurrent_tasks_ = DEFAULT_MAX_CONCURRENT_TASKS;
   active_tasks_ = 0;
   yield_expiration_ = 0;
   incoming_connections_Iter = this->_incomingConnections.begin();

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/2ecb997c/libminifi/src/core/yaml/YamlConfiguration.cpp
----------------------------------------------------------------------
diff --git a/libminifi/src/core/yaml/YamlConfiguration.cpp b/libminifi/src/core/yaml/YamlConfiguration.cpp
index 902bd89..c850afc 100644
--- a/libminifi/src/core/yaml/YamlConfiguration.cpp
+++ b/libminifi/src/core/yaml/YamlConfiguration.cpp
@@ -125,14 +125,14 @@ void YamlConfiguration::parseProcessorNodeYaml(YAML::Node processorsNode, core::
 
         auto strategyNode = getOptionalField(&procNode,
                                              "scheduling strategy",
-                                             YAML::Node("EVENT_DRIVEN"),
+                                             YAML::Node(DEFAULT_SCHEDULING_STRATEGY),
                                              CONFIG_YAML_PROCESSORS_KEY);
         procCfg.schedulingStrategy = strategyNode.as<std::string>();
         logger_->log_debug("parseProcessorNode: scheduling strategy => [%s]", procCfg.schedulingStrategy);
 
         auto periodNode = getOptionalField(&procNode,
                                            "scheduling period",
-                                           YAML::Node("1 sec"),
+                                           YAML::Node(DEFAULT_SCHEDULING_PERIOD),
                                            CONFIG_YAML_PROCESSORS_KEY);
         procCfg.schedulingPeriod = periodNode.as<std::string>();
         logger_->log_debug("parseProcessorNode: scheduling period => [%s]", procCfg.schedulingPeriod);
@@ -153,7 +153,7 @@ void YamlConfiguration::parseProcessorNodeYaml(YAML::Node processorsNode, core::
         }
 
         if (procNode["run duration nanos"]) {
-          procCfg.yieldPeriod = procNode["run duration nanos"].as<std::string>();
+          procCfg.runDurationNanos = procNode["run duration nanos"].as<std::string>();
           logger_->log_debug("parseProcessorNode: run duration nanos => [%s]", procCfg.runDurationNanos);
         }
 

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/2ecb997c/libminifi/test/unit/ManifestTests.cpp
----------------------------------------------------------------------
diff --git a/libminifi/test/unit/ManifestTests.cpp b/libminifi/test/unit/ManifestTests.cpp
new file mode 100644
index 0000000..09e278a
--- /dev/null
+++ b/libminifi/test/unit/ManifestTests.cpp
@@ -0,0 +1,143 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <memory>
+
+#include "../../include/core/Processor.h"
+#include "../../include/core/state/nodes/AgentInformation.h"
+#include "../TestBase.h"
+#include "io/ClientSocket.h"
+#include "core/Processor.h"
+#include "core/ClassLoader.h"
+
+TEST_CASE("Test Required", "[required]") {
+  minifi::state::response::ComponentManifest manifest("minifi-system");
+  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);
+  const auto &proc_0 = processors.children[0];
+  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[0];
+  REQUIRE(prop_0.children.size() >= 3);
+  const auto &prop_0_required = prop_0.children[2];
+  REQUIRE("required" == prop_0_required.name);
+  REQUIRE(!std::dynamic_pointer_cast<minifi::state::response::BoolValue>(prop_0_required.value.getValue())->getValue());
+}
+
+TEST_CASE("Test Valid Regex", "[validRegex]") {
+  minifi::state::response::ComponentManifest manifest("minifi-system");
+  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);
+  const auto &proc_0 = processors.children[0];
+  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[0];
+  REQUIRE(prop_0.children.size() >= 3);
+  const auto &df = prop_0.children[3];
+  REQUIRE("defaultValue" == df.name);
+  const auto &prop_0_valid_regex = prop_0.children[4];
+  REQUIRE("validRegex" == prop_0_valid_regex.name);
+}
+
+TEST_CASE("Test Relationships", "[rel1]") {
+  minifi::state::response::ComponentManifest manifest("minifi-system");
+  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 &relationships = proc_0.children[1];
+  REQUIRE("supportedRelationships" == relationships.name);
+  // this is because they are now nested
+  REQUIRE("supportedRelationships" == relationships.children[0].name);
+  REQUIRE("name" == relationships.children[0].children[0].name);
+  REQUIRE("failure" == relationships.children[0].children[0].value.to_string());
+  REQUIRE("description" == relationships.children[0].children[1].name);
+
+  REQUIRE("success" == relationships.children[1].children[0].value.to_string());
+  REQUIRE("description" == relationships.children[1].children[1].name);
+}
+
+TEST_CASE("Test Dependent", "[dependent]") {
+  minifi::state::response::ComponentManifest manifest("minifi-system");
+  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);
+  REQUIRE("defaultValue" == prop_0.children[3].name);
+  REQUIRE("validRegex" == prop_0.children[4].name);
+  const auto &prop_0_dependent_0 = prop_descriptors.children[2];
+  REQUIRE("Directory" == prop_0_dependent_0.name);
+}
+
+TEST_CASE("Test Scheduling Defaults", "[schedDef]") {
+  minifi::state::response::AgentManifest manifest("minifi-system");
+  auto serialized = manifest.serialize();
+  REQUIRE(serialized.size() > 0);
+  minifi::state::response::SerializedResponseNode proc_0;
+  for (const auto &node : serialized) {
+    if ("schedulingDefaults" == node.name) {
+      proc_0 = node;
+    }
+  }
+  REQUIRE(proc_0.children.size() == 4);
+  for (const auto &child : proc_0.children) {
+    if ("defaultMaxConcurrentTasks" == child.name) {
+      REQUIRE("1" == child.value.to_string());
+    } else if ("defaultRunDurationNanos" == child.name) {
+      REQUIRE("0" == child.value.to_string());
+    } else if ("defaultSchedulingPeriod" == child.name) {
+      REQUIRE("1 sec" == child.value.to_string());
+    } else if ("defaultSchedulingStrategy" == child.name) {
+      REQUIRE("TIMER_DRIVEN" == child.value.to_string());
+    } else {
+      FAIL("UNKNOWQN NODE");
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/2ecb997c/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp
----------------------------------------------------------------------
diff --git a/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp b/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp
deleted file mode 100644
index 31f9b7b..0000000
--- a/libminifi/test/unit/PropertyValidationAgentInfoTests.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-/**
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <memory>
-
-#include "../../include/core/Processor.h"
-#include "../../include/core/state/nodes/AgentInformation.h"
-#include "../TestBase.h"
-#include "io/ClientSocket.h"
-#include "core/Processor.h"
-#include "core/ClassLoader.h"
-
-TEST_CASE("Test Required", "[required]") {
-  minifi::state::response::ComponentManifest manifest("minifi-system");
-  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);
-  const auto &proc_0 = processors.children[0];
-  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[0];
-  REQUIRE(prop_0.children.size() >= 3);
-  const auto &prop_0_required = prop_0.children[2];
-  REQUIRE("required" == prop_0_required.name);
-  REQUIRE(!std::dynamic_pointer_cast<minifi::state::response::BoolValue>(prop_0_required.value.getValue())->getValue());
-}
-
-TEST_CASE("Test Valid Regex", "[validRegex]") {
-  minifi::state::response::ComponentManifest manifest("minifi-system");
-  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);
-  const auto &proc_0 = processors.children[0];
-  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[0];
-  REQUIRE(prop_0.children.size() >= 3);
-  const auto &df = prop_0.children[3];
-  REQUIRE("defaultValue" == df.name);
-  const auto &prop_0_valid_regex = prop_0.children[4];
-  REQUIRE("validRegex" == prop_0_valid_regex.name);
-}
-
-TEST_CASE("Test Relationships", "[rel1]") {
-  minifi::state::response::ComponentManifest manifest("minifi-system");
-  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 &relationships = proc_0.children[1];
-  REQUIRE("supportedRelationships" == relationships.name);
-  // this is because they are now nested
-  REQUIRE("supportedRelationships" ==  relationships.children[0].name);
-  REQUIRE("name" ==  relationships.children[0].children[0].name);
-  REQUIRE("failure" ==  relationships.children[0].children[0].value.to_string());
-  REQUIRE("description" ==  relationships.children[0].children[1].name);
-
-  REQUIRE("success" ==  relationships.children[1].children[0].value.to_string());
-  REQUIRE("description" ==  relationships.children[1].children[1].name);
-
-
-}
-
-
-TEST_CASE("Test Dependent", "[dependent]") {
-  minifi::state::response::ComponentManifest manifest("minifi-system");
-  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);
-  REQUIRE("defaultValue" == prop_0.children[3].name);
-  REQUIRE("validRegex" == prop_0.children[4].name);
-  const auto &prop_0_dependent_0 = prop_descriptors.children[2];
-  REQUIRE("Directory" == prop_0_dependent_0.name);
-}