Skip to content

Commit

Permalink
Remove --strict option for json import
Browse files Browse the repository at this point in the history
  • Loading branch information
dominiklohmann committed Jun 5, 2020
1 parent 5ce0f19 commit a093cce
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 49 deletions.
3 changes: 1 addition & 2 deletions CHANGELOG.md
Expand Up @@ -12,8 +12,7 @@ Every entry has a category for which we use the following visual abbreviations:
## Unreleased

- 🎁 The `import json` command's type restrictions are more relaxed now, and can
additionally convert from JSON strings to VAST internal data types. The new
option `--strict` allows for restoring the old behavior.
additionally convert from JSON strings to VAST internal data types.
[#891](https://github.com/tenzir/vast/pull/891)

- 🎁 VAST now supports /etc/vast/vast.conf as an additional fallback for the
Expand Down
33 changes: 11 additions & 22 deletions libvast/src/format/json.cpp
Expand Up @@ -37,7 +37,7 @@
namespace vast::format::json {
namespace {

struct strict_convert {
struct convert {
template <class T>
using expected = caf::expected<T>;
using json = vast::json;
Expand Down Expand Up @@ -136,18 +136,6 @@ struct strict_convert {
return xs;
}

template <class T, class U>
caf::expected<data> operator()(T, U) const {
VAST_ERROR_ANON("json-reader cannot convert from",
caf::detail::pretty_type_name(typeid(T)), "to",
caf::detail::pretty_type_name(typeid(U)));
return make_error(ec::syntax_error, "invalid json type");
}
};

struct relaxed_convert : strict_convert {
using strict_convert::operator();

caf::expected<data>
operator()(const json::string& str, const bool_type&) const {
if (bool x; parsers::json_boolean(str, x))
Expand Down Expand Up @@ -192,6 +180,14 @@ struct relaxed_convert : strict_convert {
return port{x};
return make_error(ec::convert_error, "cannot convert from", str, "to port");
}

template <class T, class U>
caf::expected<data> operator()(T, U) const {
VAST_ERROR_ANON("json-reader cannot convert from",
caf::detail::pretty_type_name(typeid(T)), "to",
caf::detail::pretty_type_name(typeid(U)));
return make_error(ec::syntax_error, "invalid json type");
}
};

const vast::json* lookup(std::string_view field, const vast::json::object& xs) {
Expand Down Expand Up @@ -228,7 +224,7 @@ const char* writer::name() const {
}

caf::error add(table_slice_builder& builder, const vast::json::object& xs,
const record_type& layout, conversion_policy policy) {
const record_type& layout) {
for (auto& field : layout.fields) {
auto i = lookup(field.name, xs);
// Non-existing fields are treated as empty (unset).
Expand All @@ -238,14 +234,7 @@ caf::error add(table_slice_builder& builder, const vast::json::object& xs,
"slice builder");
continue;
}
auto x = [&] {
switch (policy) {
case conversion_policy::relaxed:
return caf::visit(relaxed_convert{}, *i, field.type);
case conversion_policy::strict:
return caf::visit(strict_convert{}, *i, field.type);
}
}();
auto x = caf::visit(convert{}, *i, field.type);
if (!x)
return make_error(ec::convert_error, x.error().context(),
"could not convert", field.name, ":", to_string(*i));
Expand Down
8 changes: 2 additions & 6 deletions libvast/src/system/application.cpp
Expand Up @@ -179,10 +179,10 @@ auto make_import_command() {
source_opts("?import.csv"));
import_->add_subcommand("json", "imports JSON with schema",
documentation::vast_import_json,
json_source_opts("?import.json"));
source_opts("?import.json"));
import_->add_subcommand("suricata", "imports suricata eve json",
documentation::vast_import_suricata,
json_source_opts("?import.suricata"));
source_opts("?import.suricata"));
import_->add_subcommand("syslog", "imports syslog messages",
documentation::vast_import_syslog,
source_opts("?import.syslog"));
Expand Down Expand Up @@ -470,10 +470,6 @@ command::opts_builder source_opts(std::string_view category) {
.add<bool>("uds,d", "treat -r as listening UNIX domain socket");
}

command::opts_builder json_source_opts(std::string_view category) {
return source_opts(category).add<bool>("strict", "strict type matching");
}

command::opts_builder sink_opts(std::string_view category) {
return command::opts(category)
.add<std::string>("write,w", "path to write events to")
Expand Down
2 changes: 1 addition & 1 deletion libvast/test/format/json.cpp
Expand Up @@ -104,7 +104,7 @@ TEST(json to data) {
})json";
auto jn = unbox(to<json>(str));
auto xs = caf::get<json::object>(jn);
format::json::add(builder, xs, flat, format::json::conversion_policy::strict);
format::json::add(builder, xs, flat);
auto ptr = builder.finish();
REQUIRE(ptr);
CHECK(ptr->at(0, 11) == data{enumeration{2}});
Expand Down
15 changes: 3 additions & 12 deletions libvast/vast/format/json.hpp
Expand Up @@ -31,12 +31,9 @@

#include <caf/expected.hpp>
#include <caf/fwd.hpp>
#include <caf/settings.hpp>

namespace vast::format::json {

enum class conversion_policy { relaxed, strict };

class writer : public ostream_writer {
public:
using defaults = vast::defaults::export_::json;
Expand All @@ -54,10 +51,9 @@ class writer : public ostream_writer {
/// @param builder The builder to add the JSON object to.
/// @param xs The JSON object to add to *builder.
/// @param layout The record type describing *xs*.
/// @param policy Type conversion policy.
/// @returns An error iff the operation failed.
caf::error add(table_slice_builder& builder, const vast::json::object& xs,
const record_type& layout, conversion_policy policy);
const record_type& layout);

/// @relates reader
struct default_selector {
Expand Down Expand Up @@ -123,7 +119,7 @@ class reader final : public multi_layout_reader {
/// @param options Additional options.
/// @param in The stream of JSON objects.
explicit reader(caf::atom_value table_slice_type,
const caf::settings& options,
const caf::settings& /*options*/,
std::unique_ptr<std::istream> in = nullptr);

void reset(std::unique_ptr<std::istream> in);
Expand Down Expand Up @@ -151,7 +147,6 @@ class reader final : public multi_layout_reader {
mutable size_t num_invalid_lines_ = 0;
mutable size_t num_unknown_layouts_ = 0;
mutable size_t num_lines_ = 0;
conversion_policy conversion_policy_ = conversion_policy::relaxed;
};

// -- implementation ----------------------------------------------------------
Expand All @@ -161,12 +156,8 @@ reader<Selector>::reader(caf::atom_value table_slice_type,
const caf::settings& options,
std::unique_ptr<std::istream> in)
: super(table_slice_type) {
using namespace std::string_literals;
if (in != nullptr)
reset(std::move(in));
auto category = vast::defaults::import::json::category;
if (caf::get_or(options, category + ".strict"s, false))
conversion_policy_ = conversion_policy::strict;
}

template <class Selector>
Expand Down Expand Up @@ -265,7 +256,7 @@ caf::error reader<Selector>::read_impl(size_t max_events, size_t max_slice_size,
bptr = builder(*layout);
if (bptr == nullptr)
return make_error(ec::parse_error, "unable to get a builder");
if (auto err = add(*bptr, *xs, *layout, conversion_policy_)) {
if (auto err = add(*bptr, *xs, *layout)) {
err.context() += caf::make_message("line", lines_->line_number());
return finish(cons, err);
}
Expand Down
3 changes: 0 additions & 3 deletions libvast/vast/system/application.hpp
Expand Up @@ -36,9 +36,6 @@ void render_error(const command& root, const caf::error& err, std::ostream& os);
/// @returns default options for source commands.
command::opts_builder source_opts(std::string_view category);

/// @returns default options for JSON source commands.
command::opts_builder json_source_opts(std::string_view category);

/// @returns defaults options for sink commands.
command::opts_builder sink_opts(std::string_view category);

Expand Down
3 changes: 0 additions & 3 deletions vast.conf
Expand Up @@ -77,9 +77,6 @@ export {
; The `vast export json` command exports events formatted as JSONL (line-
; delimited JSON).
json {
; Strict type matching.
;strict = false

; For additionally available options, see export.ascii.
}

Expand Down

0 comments on commit a093cce

Please sign in to comment.