[
https://issues.apache.org/jira/browse/MINIFICPP-479?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16719469#comment-16719469
]
ASF GitHub Bot commented on MINIFICPP-479:
------------------------------------------
Github user phrocker commented on a diff in the pull request:
https://github.com/apache/nifi-minifi-cpp/pull/460#discussion_r241193264
--- Diff: libminifi/include/core/PropertyValidation.h ---
@@ -0,0 +1,347 @@
+/**
+ *
+ * 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_CORE_PROPERTYVALIDATION_H_
+#define LIBMINIFI_INCLUDE_CORE_PROPERTYVALIDATION_H_
+
+#include "core/Core.h"
+#include "core/state/Value.h"
+#include "TypedValues.h"
+#include "utils/StringUtils.h"
+#include <memory>
+
+namespace org {
+namespace apache {
+namespace nifi {
+namespace minifi {
+namespace core {
+
+class ValidationResult;
+
+class ValidationResult {
+ public:
+ bool valid() const {
+ return valid_;
+ }
+
+ class Builder {
+ public:
+ static Builder createBuilder() {
+ return Builder();
+ }
+ Builder &isValid(bool valid) {
+ valid_ = valid;
+ return *this;
+ }
+ Builder &withSubject(const std::string &subject) {
+ subject_ = subject;
+ return *this;
+ }
+ Builder &withInput(const std::string &input) {
+ input_ = input;
+ return *this;
+ }
+
+ ValidationResult build() {
+ return ValidationResult(*this);
+ }
+
+ protected:
+ bool valid_;
+ std::string subject_;
+ std::string input_;
+ friend class ValidationResult;
+ };
+ private:
+
+ bool valid_;
+ std::string subject_;
+ std::string input_;
+
+ ValidationResult(const Builder &builder)
+ : valid_(builder.valid_),
+ subject_(builder.subject_),
+ input_(builder.input_) {
+ }
+
+ friend class Builder;
+};
+
+class PropertyValidator {
+ public:
+
+ PropertyValidator(const std::string &name)
+ : name_(name) {
+ }
+ virtual ~PropertyValidator() {
+
+ }
+
+ std::string getName() const {
+ return name_;
+ }
+
+ virtual ValidationResult validate(const std::string &subject, const
std::shared_ptr<minifi::state::response::Value> &input) const = 0;
+
+ virtual ValidationResult validate(const std::string &subject, const
std::string &input) const = 0;
+
+ protected:
+ template<typename T>
+ ValidationResult _validate_internal(const std::string &subject, const
std::shared_ptr<minifi::state::response::Value> &input) const {
+ if (std::dynamic_pointer_cast<T>(input) != nullptr) {
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input->getStringValue()).isValid(true).build();
+ } else {
+ state::response::ValueNode vn;
+ vn = input->getStringValue();
+ return validate(subject, input->getStringValue());
+ }
+
+ }
+
+ std::string name_;
+};
+
+class AlwaysValid : public PropertyValidator {
+ bool always_valid_;
+ public:
+ AlwaysValid(bool isalwaysvalid, const std::string &name)
+ : always_valid_(isalwaysvalid),
+ PropertyValidator(name) {
+
+ }
+ virtual ~AlwaysValid() {
+ }
+ ValidationResult validate(const std::string &subject, const
std::shared_ptr<minifi::state::response::Value> &input) const {
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input->getStringValue()).isValid(always_valid_).build();
+ }
+
+ ValidationResult validate(const std::string &subject, const std::string
&input) const {
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(always_valid_).build();
+ }
+
+};
+
+class BooleanValidator : public PropertyValidator {
+ public:
+ BooleanValidator(const std::string &name)
+ : PropertyValidator(name) {
+ }
+ virtual ~BooleanValidator() {
+
+ }
+
+ ValidationResult validate(const std::string &subject, const
std::shared_ptr<minifi::state::response::Value> &input) const {
+ return
PropertyValidator::_validate_internal<minifi::state::response::BoolValue>(subject,
input);
+ }
+
+ ValidationResult validate(const std::string &subject, const std::string
&input) const {
+ if (utils::StringUtils::equalsIgnoreCase(input, "true") ||
utils::StringUtils::equalsIgnoreCase(input, "false"))
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(true).build();
+ else
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(false).build();
+ }
+};
+
+class IntegerValidator : public PropertyValidator {
+ public:
+ IntegerValidator(const std::string &name)
+ : PropertyValidator(name) {
+ }
+ virtual ~IntegerValidator() {
+ }
+
+ ValidationResult validate(const std::string &subject, const
std::shared_ptr<minifi::state::response::Value> &input) const {
+ return
PropertyValidator::_validate_internal<minifi::state::response::IntValue>(subject,
input);
+ }
+
+ ValidationResult validate(const std::string &subject, const std::string
&input) const {
+ try {
+ std::stoi(input);
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(true).build();
+ } catch (...) {
+
+ }
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(false).build();
+ }
+};
+
+class LongValidator : public PropertyValidator {
+ public:
+ explicit LongValidator(const std::string &name, int64_t min =
std::numeric_limits<int64_t>::min(), int64_t max =
std::numeric_limits<int64_t>::max())
+ : PropertyValidator(name),
+ min_(min),
+ max_(max) {
+ }
+ virtual ~LongValidator() {
+
+ }
+ ValidationResult validate(const std::string &subject, const
std::shared_ptr<minifi::state::response::Value> &input) const {
+ auto in64 =
std::dynamic_pointer_cast<minifi::state::response::Int64Value>(input);
+ if (in64) {
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(in64->getStringValue()).isValid(in64->getValue()
>= min_ && in64->getValue() <= max_).build();
+ } else {
+ auto intb =
std::dynamic_pointer_cast<minifi::state::response::IntValue>(input);
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(intb->getStringValue()).isValid(intb->getValue()
>= min_ && intb->getValue() <= max_).build();
+ }
+ }
+
+ ValidationResult validate(const std::string &subject, const std::string
&input) const {
+ try {
+ auto res = std::stoll(input);
+
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(res
>= min_ && res <= max_).build();
+ } catch (...) {
+
+ }
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(false).build();
+ }
+
+ private:
+ int64_t min_;
+ int64_t max_;
+};
+
+class UnsignedLongValidator : public PropertyValidator {
+ public:
+ explicit UnsignedLongValidator(const std::string &name)
+ : PropertyValidator(name) {
+ }
+ virtual ~UnsignedLongValidator() {
+
+ }
+ ValidationResult validate(const std::string &subject, const
std::shared_ptr<minifi::state::response::Value> &input) const {
+ return
PropertyValidator::_validate_internal<minifi::state::response::UInt64Value>(subject,
input);
+ }
+
+ ValidationResult validate(const std::string &subject, const std::string
&input) const {
+ try {
+ std::stoull(input);
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(true).build();
+ } catch (...) {
+
+ }
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(false).build();
+ }
+
+};
+
+class DataSizeValidator : public PropertyValidator {
+ public:
+ DataSizeValidator(const std::string &name)
+ : PropertyValidator(name) {
+ }
+ virtual ~DataSizeValidator() {
+
+ }
+ ValidationResult validate(const std::string &subject, const
std::shared_ptr<minifi::state::response::Value> &input) const {
+ return
PropertyValidator::_validate_internal<core::DataSizeValue>(subject, input);
+ }
+
+ ValidationResult validate(const std::string &subject, const std::string
&input) const {
+ uint64_t out;
+ if (core::DataSizeValue::StringToInt(input, out))
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(true).build();
+ else
+ return
ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(false).build();
+ }
+};
+
+class PortValidator : public LongValidator {
+ public:
+ PortValidator(const std::string &name)
+ : LongValidator(name, 1, 65535) {
+ }
+ virtual ~PortValidator() {
+
+ }
+};
+
+class DataTimeValidator : public PropertyValidator {
--- End diff --
Good call thanks. I think the name in NiFi is TIME_PERIOD_VALIDATOR, so I
will probably rename this. It's a little old in its name.
> Incorporate property validation information into manifest
> ---------------------------------------------------------
>
> Key: MINIFICPP-479
> URL: https://issues.apache.org/jira/browse/MINIFICPP-479
> Project: NiFi MiNiFi C++
> Issue Type: Improvement
> Reporter: Andrew Christianson
> Assignee: Mr TheSegfault
> Priority: Major
>
> High-level intent is to avoid round-trip to c2 to know that flow is valid
> (or, invalid in common/trivial ways).
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)