Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

434 add validation to observations #436

Merged
merged 10 commits into from
Apr 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/build-docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ on:
jobs:
# this workflow contains a single job called "build"
build:
# Do not build if it is an RC build
if: ${{ ! contains(github.ref_name, "RC") }}

# the type of runner that the job will run on
runs-on: ubuntu-latest
strategy:
Expand Down
9 changes: 4 additions & 5 deletions src/mtconnect/agent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,8 @@
#include "mtconnect/sink/rest_sink/file_cache.hpp"
#include "mtconnect/sink/rest_sink/session.hpp"
#include "mtconnect/utilities.hpp"
#include "mtconnect/version.h"

#include "mtconnect/validation/observations.hpp"
#include "mtconnect/version.h"

using namespace std;

Expand Down Expand Up @@ -171,13 +170,14 @@ namespace mtconnect {

if (!m_observationsInitialized)
{
if (m_intSchemaVersion < SCHEMA_VERSION(2, 5) && IsOptionSet(m_options, mtconnect::configuration::Validation))
if (m_intSchemaVersion < SCHEMA_VERSION(2, 5) &&
IsOptionSet(m_options, mtconnect::configuration::Validation))
{
m_validation = false;
for (auto &printer : m_printers)
printer.second->setValidation(false);
}

for (auto device : m_deviceIndex)
initializeDataItems(device);

Expand All @@ -201,7 +201,6 @@ namespace mtconnect {
}

m_observationsInitialized = true;

}
}

Expand Down
42 changes: 26 additions & 16 deletions src/mtconnect/pipeline/validator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,37 +27,41 @@

namespace mtconnect::pipeline {
using namespace entity;

/// @brief Map a token list to data items or asset types

/// @brief Validate obsrvations based on Controlled Vocabularies
///
/// - Does not validate data sets and tables
/// - Validates all events, not samples or conditions
class AGENT_LIB_API Validator : public Transform
{
public:
Validator(const Validator &) = default;
Validator(PipelineContextPtr context)
: Transform("Validator"),
m_contract(context->m_contract.get())
: Transform("Validator"), m_contract(context->m_contract.get())
{
m_guard = TypeGuard<observation::Event>(RUN) || TypeGuard<observation::Observation>(SKIP);
}


/// @brief validate the Event
/// @param entity The Event entity
/// @returns modified entity with quality and deprecated properties
EntityPtr operator()(entity::EntityPtr &&entity) override
{
using namespace observation;
using namespace mtconnect::validation::observations;
auto evt = std::dynamic_pointer_cast<Event>(entity);

auto di = evt->getDataItem();
auto &type = di->getType();
auto &value = evt->getValue<std::string>();

if (value == "UNAVAILABLE")
if (evt->isUnavailable() || di->isDataSet())
{
evt->setProperty("quality", std::string("VALID"));
}
else
{
auto &value = evt->getValue<std::string>();

// Optimize
auto vocab = ControlledVocabularies.find(type);
auto vocab = ControlledVocabularies.find(evt->getName());
if (vocab != ControlledVocabularies.end())
{
auto &lits = vocab->second;
Expand All @@ -67,7 +71,12 @@ namespace mtconnect::pipeline {
if (lit != lits.end())
{
evt->setProperty("quality", std::string("VALID"));
// Check for deprecated

// Check if deprecated
if (lit->second > 0 && m_contract->getSchemaVersion() > lit->second)
{
evt->setProperty("deprecated", true);
}
}
else
{
Expand All @@ -76,13 +85,14 @@ namespace mtconnect::pipeline {
auto &id = di->getId();
if (m_logOnce.count(id) < 1)
{
LOG(warning) << id << ": Invalid value for '" << type << "' " << evt->getValue<std::string>();
LOG(warning) << "DataItem '" << id << "': Invalid value for '" << evt->getName()
<< "': '" << evt->getValue<std::string>() << '\'';
m_logOnce.insert(id);
}
else
{
LOG(trace) << id << ": Invalid value for '" << type << "' " << evt->getValue<std::string>();

LOG(trace) << "DataItem '" << id << "': Invalid value for '" << evt->getName()
<< "': '" << evt->getValue<std::string>() << '\'';
}
}
}
Expand All @@ -96,7 +106,7 @@ namespace mtconnect::pipeline {
evt->setProperty("quality", std::string("UNVERIFIABLE"));
}
}

return next(std::move(evt));
}

Expand Down
22 changes: 9 additions & 13 deletions src/mtconnect/printer/json_printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ namespace mtconnect::printer {
template <typename T>
inline void header(AutoJsonObject<T> &obj, const string &version, const string &hostname,
const uint64_t instanceId, const unsigned int bufferSize,
const string &schemaVersion, const string modelChangeTime,
bool validation)
const string &schemaVersion, const string modelChangeTime, bool validation)
{
obj.AddPairs("version", version, "creationTime", getCurrentTime(GMT), "testIndicator", false,
"instanceId", instanceId, "sender", hostname, "schemaVersion", schemaVersion);
Expand All @@ -72,18 +71,17 @@ namespace mtconnect::printer {
obj.AddPairs("bufferSize", bufferSize);
if (validation)
obj.AddPairs("validation", true);

}

template <typename T>
inline void probeAssetHeader(AutoJsonObject<T> &obj, const string &version,
const string &hostname, const uint64_t instanceId,
const unsigned int bufferSize, const unsigned int assetBufferSize,
const unsigned int assetCount, const string &schemaVersion,
const string modelChangeTime,
const bool validation)
const string modelChangeTime, const bool validation)
{
header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation);
header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime,
validation);
obj.AddPairs("assetBufferSize", assetBufferSize, "assetCount", assetCount);
}

Expand All @@ -92,10 +90,10 @@ namespace mtconnect::printer {
const uint64_t instanceId, const unsigned int bufferSize,
const uint64_t nextSequence, const uint64_t firstSequence,
const uint64_t lastSequence, const string &schemaVersion,
const string modelChangeTime,
const bool validation)
const string modelChangeTime, const bool validation)
{
header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime, validation);
header(obj, version, hostname, instanceId, bufferSize, schemaVersion, modelChangeTime,
validation);
obj.AddPairs("nextSequence", nextSequence, "lastSequence", lastSequence, "firstSequence",
firstSequence);
}
Expand Down Expand Up @@ -213,8 +211,7 @@ namespace mtconnect::printer {
{
AutoJsonObject obj(writer, "Header");
probeAssetHeader(obj, m_version, m_senderName, instanceId, 0, bufferSize, assetCount,
*m_schemaVersion, m_modelChangeTime,
m_validation);
*m_schemaVersion, m_modelChangeTime, m_validation);
}
{
obj.Key("Assets");
Expand Down Expand Up @@ -412,8 +409,7 @@ namespace mtconnect::printer {
{
AutoJsonObject obj(writer, "Header");
streamHeader(obj, m_version, m_senderName, instanceId, bufferSize, nextSeq, firstSeq,
lastSeq, *m_schemaVersion, m_modelChangeTime,
m_validation);
lastSeq, *m_schemaVersion, m_modelChangeTime, m_validation);
}

{
Expand Down
13 changes: 7 additions & 6 deletions src/mtconnect/printer/printer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ namespace mtconnect {
public:
/// @brief construct a printer
/// @param pretty `true` if content should be pretty printed
Printer(bool pretty = false, bool validation = false) : m_pretty(pretty), m_validation(validation) {}
Printer(bool pretty = false, bool validation = false)
: m_pretty(pretty), m_validation(validation)
{}
virtual ~Printer() = default;

/// @brief Generate an MTConnect Error document
Expand Down Expand Up @@ -145,19 +147,18 @@ namespace mtconnect {
const_cast<Printer *>(this)->m_schemaVersion.emplace(ver);
}
}

/// @brief Get validation header flag state
/// @returns validation state
bool getValidation() const { return m_validation; }

/// @brief sets validation state
/// @param validation the validation state
void setValidation(bool v) { m_validation = v; }


protected:
bool m_pretty; //< Turns pretty printing on
bool m_validation; //< Sets validation flag in header
bool m_pretty; //< Turns pretty printing on
bool m_validation; //< Sets validation flag in header
std::string m_modelChangeTime;
std::optional<std::string> m_schemaVersion;
std::string m_senderName {"localhost"};
Expand Down
7 changes: 5 additions & 2 deletions src/mtconnect/printer/xml_printer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,10 @@ namespace mtconnect::printer {
xmlBufferPtr m_buf;
};

XmlPrinter::XmlPrinter(bool pretty, bool validation) : Printer(pretty, validation) { NAMED_SCOPE("xml.printer"); }
XmlPrinter::XmlPrinter(bool pretty, bool validation) : Printer(pretty, validation)
{
NAMED_SCOPE("xml.printer");
}

void XmlPrinter::addDevicesNamespace(const std::string &urn, const std::string &location,
const std::string &prefix)
Expand Down Expand Up @@ -636,7 +639,7 @@ namespace mtconnect::printer {

addAttribute(writer, "sender", m_senderName);
addAttribute(writer, "instanceId", to_string(instanceId));

if (m_validation)
addAttribute(writer, "validation", "true"s);

Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/source/adapter/adapter_pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ namespace mtconnect {
// Convert values
if (IsOptionSet(m_options, configuration::ConversionRequired))
next = next->bind(make_shared<ConvertSample>());

// Validate Values
if (IsOptionSet(m_options, configuration::Validation))
next = next->bind(make_shared<Validator>(m_context));
Expand Down
2 changes: 1 addition & 1 deletion src/mtconnect/source/loopback_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ namespace mtconnect::source {
void LoopbackPipeline::build(const ConfigOptions &options)
{
m_options = options;

clear();
TransformPtr next = m_start;

Expand Down
Loading
Loading