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");
+}