blob: 800a3f503f551008ef0a2c0ba0773a4dab013b65 [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_CORE_PROPERTYVALIDATION_H_
#define LIBMINIFI_INCLUDE_CORE_PROPERTYVALIDATION_H_
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include "core/Core.h"
#include "core/state/Value.h"
#include "TypedValues.h"
#include "utils/StringUtils.h"
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_{ false };
std::string subject_;
std::string input_;
friend class ValidationResult;
};
private:
bool valid_;
std::string subject_;
std::string input_;
ValidationResult(const Builder &builder) // NOLINT
: valid_(builder.valid_),
subject_(builder.subject_),
input_(builder.input_) {
}
friend class Builder;
};
class PropertyValidator {
public:
PropertyValidator(std::string name) // NOLINT
: name_(std::move(name)) {
}
virtual ~PropertyValidator() = default;
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)
: PropertyValidator(name),
always_valid_(isalwaysvalid) {
}
~AlwaysValid() override = default;
ValidationResult validate(const std::string &subject, const std::shared_ptr<minifi::state::response::Value> &input) const override {
return ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input->getStringValue()).isValid(always_valid_).build();
}
ValidationResult validate(const std::string &subject, const std::string &input) const override {
return ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(always_valid_).build();
}
};
class BooleanValidator : public PropertyValidator {
public:
BooleanValidator(const std::string &name) // NOLINT
: PropertyValidator(name) {
}
~BooleanValidator() override = default;
ValidationResult validate(const std::string &subject, const std::shared_ptr<minifi::state::response::Value> &input) const override {
return PropertyValidator::_validate_internal<minifi::state::response::BoolValue>(subject, input);
}
ValidationResult validate(const std::string &subject, const std::string &input) const override {
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) // NOLINT
: PropertyValidator(name) {
}
~IntegerValidator() override = default;
ValidationResult validate(const std::string &subject, const std::shared_ptr<minifi::state::response::Value> &input) const override {
return PropertyValidator::_validate_internal<minifi::state::response::IntValue>(subject, input);
}
ValidationResult validate(const std::string &subject, const std::string &input) const override {
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 UnsignedIntValidator : public PropertyValidator {
public:
explicit UnsignedIntValidator(const std::string &name)
: PropertyValidator(name) {
}
~UnsignedIntValidator() override = default;
ValidationResult validate(const std::string &subject, const std::shared_ptr<minifi::state::response::Value> &input) const override {
return PropertyValidator::_validate_internal<minifi::state::response::UInt32Value>(subject, input);
}
ValidationResult validate(const std::string &subject, const std::string &input) const override {
try {
auto negative = input.find_first_of('-') != std::string::npos;
if (negative) {
throw std::out_of_range("non negative expected");
}
std::stoul(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) {
}
~LongValidator() override = default;
ValidationResult validate(const std::string &subject, const std::shared_ptr<minifi::state::response::Value> &input) const override {
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 override {
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) {
}
~UnsignedLongValidator() override = default;
ValidationResult validate(const std::string &subject, const std::shared_ptr<minifi::state::response::Value> &input) const override {
return PropertyValidator::_validate_internal<minifi::state::response::UInt64Value>(subject, input);
}
ValidationResult validate(const std::string &subject, const std::string &input) const override {
try {
auto negative = input.find_first_of('-') != std::string::npos;
if (negative) {
throw std::out_of_range("non negative expected");
}
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 NonBlankValidator : public PropertyValidator {
public:
explicit NonBlankValidator(const std::string& name)
: PropertyValidator(name) {
}
~NonBlankValidator() override = default;
ValidationResult validate(const std::string& subject, const std::shared_ptr<minifi::state::response::Value>& input) const final {
return validate(subject, input->getStringValue());
}
ValidationResult validate(const std::string& subject, const std::string& input) const final {
return ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(utils::StringUtils::trimLeft(input).size()).build();
}
};
class DataSizeValidator : public PropertyValidator {
public:
DataSizeValidator(const std::string &name) // NOLINT
: PropertyValidator(name) {
}
~DataSizeValidator() override = default;
ValidationResult validate(const std::string &subject, const std::shared_ptr<minifi::state::response::Value> &input) const override {
return PropertyValidator::_validate_internal<core::DataSizeValue>(subject, input);
}
ValidationResult validate(const std::string &subject, const std::string &input) const override {
uint64_t out;
return ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(core::DataSizeValue::StringToInt(input, out)).build();
}
};
class PortValidator : public LongValidator {
public:
PortValidator(const std::string &name) // NOLINT
: LongValidator(name, 1, 65535) {
}
~PortValidator() override = default;
};
// Use only for specifying listen ports, where 0 means a randomly chosen one!
class ListenPortValidator : public LongValidator {
public:
ListenPortValidator(const std::string &name) // NOLINT
: LongValidator(name, 0, 65535) {
}
~ListenPortValidator() override = default;
};
class TimePeriodValidator : public PropertyValidator {
public:
TimePeriodValidator(const std::string &name) // NOLINT
: PropertyValidator(name) {
}
~TimePeriodValidator() override = default;
ValidationResult validate(const std::string &subject, const std::shared_ptr<minifi::state::response::Value> &input) const override {
return PropertyValidator::_validate_internal<core::TimePeriodValue>(subject, input);
}
ValidationResult validate(const std::string &subject, const std::string &input) const override {
uint64_t out;
TimeUnit outTimeUnit;
return ValidationResult::Builder::createBuilder().withSubject(subject).withInput(input).isValid(core::TimePeriodValue::StringToTime(input, out, outTimeUnit)).build();
}
};
// STATIC DEFINITIONS
class StandardValidators {
public:
static const gsl::not_null<std::shared_ptr<PropertyValidator>> &getValidator(const std::shared_ptr<minifi::state::response::Value> &input) {
static StandardValidators init;
if (std::dynamic_pointer_cast<core::DataSizeValue>(input) != nullptr) {
return init.DATA_SIZE_VALIDATOR;
} else if (std::dynamic_pointer_cast<core::TimePeriodValue>(input) != nullptr) {
return init.TIME_PERIOD_VALIDATOR;
} else if (std::dynamic_pointer_cast<minifi::state::response::BoolValue>(input) != nullptr) {
return init.BOOLEAN_VALIDATOR;
} else if (std::dynamic_pointer_cast<minifi::state::response::IntValue>(input) != nullptr) {
return init.INTEGER_VALIDATOR;
} else if (std::dynamic_pointer_cast<minifi::state::response::UInt32Value>(input) != nullptr) {
return init.UNSIGNED_INT_VALIDATOR;;
} else if (std::dynamic_pointer_cast<minifi::state::response::Int64Value>(input) != nullptr) {
return init.LONG_VALIDATOR;
} else if (std::dynamic_pointer_cast<minifi::state::response::UInt64Value>(input) != nullptr) {
return init.UNSIGNED_LONG_VALIDATOR;
} else {
return org::apache::nifi::minifi::core::StandardValidators::VALID_VALIDATOR();
}
}
static const gsl::not_null<std::shared_ptr<PropertyValidator>>& NON_BLANK_VALIDATOR() {
static gsl::not_null<std::shared_ptr<PropertyValidator>> validator(std::make_shared<NonBlankValidator>("NON_BLANK_VALIDATOR"));
return validator;
}
static const gsl::not_null<std::shared_ptr<PropertyValidator>>& VALID_VALIDATOR() {
static gsl::not_null<std::shared_ptr<PropertyValidator>> validator(std::make_shared<AlwaysValid>(true, "VALID"));
return validator;
}
static gsl::not_null<std::shared_ptr<PropertyValidator>> PORT_VALIDATOR() {
static gsl::not_null<std::shared_ptr<PropertyValidator>> validator(std::make_shared<PortValidator>("PORT_VALIDATOR"));
return validator;
}
static gsl::not_null<std::shared_ptr<PropertyValidator>> LISTEN_PORT_VALIDATOR() {
static gsl::not_null<std::shared_ptr<PropertyValidator>> validator(std::make_shared<ListenPortValidator>("PORT_VALIDATOR"));
return validator;
}
private:
gsl::not_null<std::shared_ptr<PropertyValidator>> INVALID;
gsl::not_null<std::shared_ptr<PropertyValidator>> INTEGER_VALIDATOR;
gsl::not_null<std::shared_ptr<PropertyValidator>> UNSIGNED_INT_VALIDATOR;
gsl::not_null<std::shared_ptr<PropertyValidator>> LONG_VALIDATOR;
gsl::not_null<std::shared_ptr<PropertyValidator>> UNSIGNED_LONG_VALIDATOR;
gsl::not_null<std::shared_ptr<PropertyValidator>> BOOLEAN_VALIDATOR;
gsl::not_null<std::shared_ptr<PropertyValidator>> DATA_SIZE_VALIDATOR;
gsl::not_null<std::shared_ptr<PropertyValidator>> TIME_PERIOD_VALIDATOR;
StandardValidators();
};
} // namespace core
} // namespace minifi
} // namespace nifi
} // namespace apache
} // namespace org
#endif // LIBMINIFI_INCLUDE_CORE_PROPERTYVALIDATION_H_