blob: de9261266890c5e767649605de4f47e1e28312a9 [file] [log] [blame]
/**
*
* 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.
*/
#ifndef LIBMINIFI_INCLUDE_AGENT_BUILD_DESCRIPTION_H_
#define LIBMINIFI_INCLUDE_AGENT_BUILD_DESCRIPTION_H_
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "core/expect.h"
namespace org {
namespace apache {
namespace nifi {
namespace minifi {
class ClassDescription {
public:
explicit ClassDescription(std::string name)
: class_name_(name),
dynamic_properties_(false),
dynamic_relationships_(false),
is_controller_service_(false) {
}
explicit ClassDescription(std::string name, std::map<std::string, core::Property> props, bool dyn_prop)
: class_name_(name),
class_properties_(props),
dynamic_properties_(dyn_prop),
dynamic_relationships_(false),
is_controller_service_(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),
is_controller_service_(false) {
}
std::string class_name_;
std::map<std::string, core::Property> class_properties_;
std::vector<core::Relationship> class_relationships_;
bool dynamic_properties_;
bool dynamic_relationships_;
bool is_controller_service_;
};
struct Components {
std::vector<ClassDescription> processors_;
std::vector<ClassDescription> controller_services_;
std::vector<ClassDescription> other_components_;
};
struct BundleDetails {
std::string artifact;
std::string group;
std::string version;
};
class ExternalBuildDescription {
private:
static std::vector<struct BundleDetails> &getExternal() {
static std::vector<struct BundleDetails> external_groups;
return external_groups;
}
static std::map<std::string, struct Components> &getExternalMappings() {
static std::map<std::string, struct Components> external_mappings;
return external_mappings;
}
public:
static void addExternalComponent(struct BundleDetails details, const ClassDescription &description) {
bool found = false;
for (const auto &d : getExternal()) {
if (d.artifact == details.artifact) {
found = true;
break;
}
}
if (!found) {
getExternal().push_back(details);
}
if (description.is_controller_service_) {
getExternalMappings()[details.artifact].controller_services_.push_back(description);
} else {
getExternalMappings()[details.artifact].processors_.push_back(description);
}
}
static struct Components getClassDescriptions(const std::string &group) {
return getExternalMappings()[group];
}
static std::vector<struct BundleDetails> getExternalGroups() {
return getExternal();
}
};
class BuildDescription {
public:
static struct Components getClassDescriptions(const std::string group = "minifi-system") {
static std::map<std::string, struct Components> class_mappings;
#ifndef WIN32
if (UNLIKELY(IsNullOrEmpty(class_mappings[group].processors_) && IsNullOrEmpty(class_mappings[group].processors_))) {
#else
if (class_mappings[group].processors_.empty()) {
#endif
for (auto clazz : core::ClassLoader::getDefaultClassLoader().getClasses(group)) {
std::string class_name = clazz;
auto lastOfIdx = clazz.find_last_of("::");
if (lastOfIdx != std::string::npos) {
lastOfIdx++; // if a value is found, increment to move beyond the .
size_t nameLength = clazz.length() - lastOfIdx;
class_name = clazz.substr(lastOfIdx, nameLength);
}
auto obj = core::ClassLoader::getDefaultClassLoader().instantiate(class_name, class_name);
std::shared_ptr<core::ConfigurableComponent> component = std::dynamic_pointer_cast<core::ConfigurableComponent>(obj);
std::string classDescriptionName = clazz;
utils::StringUtils::replaceAll(classDescriptionName, "::", ".");
ClassDescription description(classDescriptionName);
if (nullptr != component) {
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.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);
} else {
class_mappings[group].other_components_.emplace_back(description);
}
}
}
}
return class_mappings[group];
}
}; // NOLINT
} // namespace minifi
} // namespace nifi
} // namespace apache
} // namespace org
#endif // LIBMINIFI_INCLUDE_AGENT_BUILD_DESCRIPTION_H_