LSCL/LIR: enable plugins to have nested hash directives (#8751)

A regression was introduced in the new LSCL/LIR implementation in 6.0, in
which configurations that had nested hashes produced valid treetop-ASTs that
could not produce a valid LIR; the values in an `LSCL::AST::Hash` were
assumed to implement `ValueExpression`, but `LSCL::AST::Hash#expr` produced
an unwrapped `RubyHash`.

By making `LSCL::AST::Hash#expr` emit a `ValueExpression` _representing_ a
`RubyHash`, and relying on the existing code that deals with `ValueExpression`
appropriately, we can re-enable deeply-nested hashes in configs.
This commit is contained in:
Ry Biesemeyer 2017-11-28 12:09:25 -08:00 committed by GitHub
parent 9f3879afd0
commit 84dc5f6844
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 1 deletions

View file

@ -199,7 +199,7 @@ module LogStashCompilerLSCLGrammar; module LogStash; module Compiler; module LSC
def expr
validate!
::Hash[recursive_select(HashEntry).map(&:expr)]
jdsl.eValue(source_meta, ::Hash[recursive_select(HashEntry).map(&:expr)])
end
end

View file

@ -221,6 +221,62 @@ describe LogStash::Compiler do
it "should merge the contents of the individual directives" do
expect(c_plugin).to ir_eql(j.iPlugin(FILTER, "grok", expected_plugin_args))
end
describe "a filter plugin that has nested Hash directives" do
let(:source) { "input { } filter { #{plugin_source} } output { } " }
let(:plugin_source) do
<<-FILTER
matryoshka {
key => "%{host}"
filter_options => {
string => "string"
integer => 3
nested => { # <-- This is nested hash!
string => "nested-string"
integer => 7
"quoted-key-string" => "nested-quoted-key-string"
"quoted-key-integer" => 31
deep => { # <-- This is deeper nested hash!
string => "deeply-nested-string"
integer => 127
"quoted-key-string" => "deeply-nested-quoted-key-string"
"quoted-key-integer" => 8191
}
}
}
ttl => 5
}
FILTER
end
subject(:c_plugin) { compiled[:filter] }
let(:expected_plugin_args) do
{
"key" => "%{host}",
"filter_options" => {
"string" => "string",
"integer" => 3,
"nested" => { # <-- This is nested hash!
"string" => "nested-string",
"integer" => 7,
"quoted-key-string" => "nested-quoted-key-string",
"quoted-key-integer" => 31,
"deep" => { # <-- This is deeper nested hash!
"string" => "deeply-nested-string",
"integer" => 127,
"quoted-key-string" => "deeply-nested-quoted-key-string",
"quoted-key-integer" => 8191
}
}
},
"ttl" => 5
}
end
it "should produce a nested ::Hash object" do
expect(c_plugin).to ir_eql(j.iPlugin(FILTER, "matryoshka", expected_plugin_args))
end
end
end
end

View file

@ -6,6 +6,7 @@ import org.logstash.common.SourceWithMetadata;
import java.math.BigDecimal;
import java.util.List;
import org.jruby.RubyHash;
/**
* Created by andrewvc on 9/13/16.
@ -25,6 +26,7 @@ public class ValueExpression extends Expression {
value instanceof BigDecimal ||
value instanceof String ||
value instanceof List ||
value instanceof RubyHash ||
value instanceof java.time.Instant
)) {
// This *should* be caught by the treetop grammar, but we need this case just in case there's a bug