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

[nifi-minifi-cpp] 02/03: MINIFICPP-1722 - Restore 'artifact' field

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

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

commit 78050f302e2874d903c92b71ecc55c7481552bf6
Author: Adam Debreceni <ad...@apache.org>
AuthorDate: Thu Jan 13 12:18:05 2022 +0100

    MINIFICPP-1722 - Restore 'artifact' field
    
    Signed-off-by: Gabor Gyimesi <ga...@gmail.com>
    
    This closes #1240
---
 .../include/core/state/nodes/AgentInformation.h    |   5 +-
 libminifi/test/unit/ComponentManifestTests.cpp     | 101 +++++++++++++++++++++
 2 files changed, 104 insertions(+), 2 deletions(-)

diff --git a/libminifi/include/core/state/nodes/AgentInformation.h b/libminifi/include/core/state/nodes/AgentInformation.h
index 0231d22..dcd1b76 100644
--- a/libminifi/include/core/state/nodes/AgentInformation.h
+++ b/libminifi/include/core/state/nodes/AgentInformation.h
@@ -174,19 +174,20 @@ class ComponentManifest : public DeviceInformation {
               SerializedResponseNode allowed_type;
               allowed_type.name = "typeProvidedByValue";
               for (const auto &type : allowed_types) {
+                std::string class_name = utils::StringUtils::split(type, "::").back();
                 SerializedResponseNode typeNode;
                 typeNode.name = "type";
                 std::string typeClazz = type;
                 utils::StringUtils::replaceAll(typeClazz, "::", ".");
                 typeNode.value = typeClazz;
-                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).value_or("");
+                artifact.value = core::ClassLoader::getDefaultClassLoader().getGroupForClass(class_name).value_or("");
                 allowed_type.children.push_back(typeNode);
                 allowed_type.children.push_back(bgroup);
                 allowed_type.children.push_back(artifact);
diff --git a/libminifi/test/unit/ComponentManifestTests.cpp b/libminifi/test/unit/ComponentManifestTests.cpp
new file mode 100644
index 0000000..0d81379
--- /dev/null
+++ b/libminifi/test/unit/ComponentManifestTests.cpp
@@ -0,0 +1,101 @@
+/**
+ *
+ * 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.
+ */
+
+#undef LOAD_EXTENSIONS
+#include "../TestBase.h"
+#include "core/ConfigurableComponent.h"
+#include "core/controller/ControllerService.h"
+#include "core/Resource.h"
+#include "core/state/nodes/AgentInformation.h"
+
+using minifi::state::response::SerializedResponseNode;
+
+SerializedResponseNode& get(SerializedResponseNode& node, const std::string& field) {
+  REQUIRE(!node.array);
+  for (auto& child : node.children) {
+    if (child.name == field) return child;
+  }
+  throw std::logic_error("No field '" + field + "'");
+}
+
+namespace test::apple {
+
+class ExampleService : public core::controller::ControllerService {
+ public:
+  using ControllerService::ControllerService;
+
+  bool canEdit() override { return false; }
+  bool supportsDynamicProperties() override { return false; }
+  void yield() override {}
+  bool isRunning() override { return false; }
+  bool isWorkAvailable() override { return false; }
+};
+
+REGISTER_RESOURCE(ExampleService, "An example service");
+
+class ExampleProcessor : public core::Processor {
+ public:
+  using Processor::Processor;
+  static core::Property ExampleProperty;
+
+  void initialize() override {
+    setSupportedProperties({ExampleProperty});
+  }
+};
+
+core::Property ExampleProcessor::ExampleProperty(
+    core::PropertyBuilder::createProperty("Example Property")
+    ->withDescription("An example property")
+    ->isRequired(false)
+    ->asType<ExampleService>()
+    ->build());
+
+REGISTER_RESOURCE(ExampleProcessor, "An example processor");
+
+}  // namespace test::apple
+
+TEST_CASE("Manifest indicates property type requirement") {
+  minifi::state::response::ComponentManifest manifest("minifi-system");
+  auto nodes = manifest.serialize();
+  REQUIRE(nodes.size() == 1);
+  REQUIRE(nodes.at(0).name == "componentManifest");
+
+  auto& processors = get(nodes.at(0), "processors").children;
+
+  auto example_proc_it = std::find_if(processors.begin(), processors.end(), [&] (auto& proc) {
+    return get(proc, "type").value == "test.apple.ExampleProcessor";
+  });
+  REQUIRE(example_proc_it != processors.end());
+
+  auto& properties = get(*example_proc_it, "propertyDescriptors").children;
+
+  auto prop_it = std::find_if(properties.begin(), properties.end(), [&] (auto& prop) {
+    return get(prop, "name").value == "Example Property";
+  });
+
+  REQUIRE(prop_it != properties.end());
+
+  // TODO(adebreceni): based on PropertyBuilder::asType a property could accept
+  //    multiple types, these would be dumped into the same object as the type of
+  //    field "typeProvidedByValue" is not an array but an object
+  auto& type = get(*prop_it, "typeProvidedByValue");
+
+  REQUIRE(get(type, "type").value == "test.apple.ExampleService");
+  REQUIRE(get(type, "group").value == GROUP_STR);  // fix string
+  REQUIRE(get(type, "artifact").value == "minifi-system");
+}