mirror of
https://github.com/elastic/logstash.git
synced 2025-04-24 06:37:19 -04:00
#9747 Fix Java Execution compilation breaking for datasets with more than 255 parents
Fixes #9755
This commit is contained in:
parent
c56d62f4ae
commit
99b5f87f86
3 changed files with 67 additions and 27 deletions
|
@ -8,9 +8,7 @@ import java.nio.charset.StandardCharsets;
|
|||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
@ -26,6 +24,9 @@ import org.codehaus.janino.SimpleCompiler;
|
|||
*/
|
||||
public final class ComputeStepSyntaxElement<T extends Dataset> {
|
||||
|
||||
public static final VariableDefinition CTOR_ARGUMENT =
|
||||
new VariableDefinition(Map.class, "arguments");
|
||||
|
||||
private static final Path SOURCE_DIR = debugDir();
|
||||
|
||||
private static final ISimpleCompiler COMPILER = new SimpleCompiler();
|
||||
|
@ -82,7 +83,7 @@ public final class ComputeStepSyntaxElement<T extends Dataset> {
|
|||
);
|
||||
CLASS_CACHE.put(this, clazz);
|
||||
}
|
||||
return (T) clazz.<T>getConstructor(ctorTypes()).newInstance(ctorArguments());
|
||||
return (T) clazz.<T>getConstructor(Map.class).newInstance(ctorArguments());
|
||||
} catch (final CompileException | ClassNotFoundException | IOException
|
||||
| NoSuchMethodException | InvocationTargetException | InstantiationException
|
||||
| IllegalAccessException ex) {
|
||||
|
@ -141,22 +142,16 @@ public final class ComputeStepSyntaxElement<T extends Dataset> {
|
|||
return sourceDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Array of constructor argument types with the same ordering that is used by
|
||||
* {@link #ctorArguments()}.
|
||||
*/
|
||||
private Class<?>[] ctorTypes() {
|
||||
return fields.ctorAssigned().getFields().stream()
|
||||
.map(FieldDefinition::asVariable)
|
||||
.map(typedVar -> typedVar.type).toArray(Class<?>[]::new);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Array of constructor arguments
|
||||
*/
|
||||
private Object[] ctorArguments() {
|
||||
return fields.ctorAssigned().getFields().stream()
|
||||
.map(FieldDefinition::getCtorArgument).toArray();
|
||||
private Map<String, Object> ctorArguments() {
|
||||
final Map<String, Object> result = new HashMap<>();
|
||||
fields.ctorAssigned().getFields().forEach(
|
||||
fieldDefinition ->
|
||||
result.put(fieldDefinition.getName(), fieldDefinition.getCtorArgument())
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,20 +171,30 @@ public final class ComputeStepSyntaxElement<T extends Dataset> {
|
|||
private String fieldsAndCtor(final String name) {
|
||||
final Closure constructor = new Closure();
|
||||
final FieldDeclarationGroup ctorFields = fields.ctorAssigned();
|
||||
final Collection<VariableDefinition> ctor = new ArrayList<>();
|
||||
for (final FieldDefinition field : ctorFields.getFields()) {
|
||||
if (field.getCtorArgument() != null) {
|
||||
final String fieldName = field.getName();
|
||||
final VariableDefinition fieldVar = field.asVariable();
|
||||
final VariableDefinition argVar =
|
||||
fieldVar.rename(SyntaxFactory.join(fieldName, "argument"));
|
||||
constructor.add(SyntaxFactory.assignment(fieldVar.access(), argVar.access()));
|
||||
ctor.add(argVar);
|
||||
constructor.add(
|
||||
SyntaxFactory.assignment(
|
||||
fieldVar.access(),
|
||||
SyntaxFactory.cast(
|
||||
fieldVar.type,
|
||||
CTOR_ARGUMENT.access().call(
|
||||
"get",
|
||||
SyntaxFactory.value(
|
||||
SyntaxFactory.join("\"", field.getName(), "\"")
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
return combine(
|
||||
ctorFields,
|
||||
MethodSyntaxElement.constructor(name, constructor.add(fields.afterInit()), ctor)
|
||||
MethodSyntaxElement.constructor(
|
||||
name, constructor.add(fields.afterInit())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package org.logstash.config.ir.compiler;
|
|||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
import org.jruby.RubyArray;
|
||||
|
@ -15,12 +16,13 @@ interface MethodSyntaxElement extends SyntaxElement {
|
|||
* Builds a constructor from the given method body and arguments.
|
||||
* @param classname Name of the Class
|
||||
* @param body Constructor Method Body
|
||||
* @param arguments Method Argument Definitions
|
||||
* @return Method Syntax
|
||||
*/
|
||||
static MethodSyntaxElement constructor(final String classname, final Closure body,
|
||||
final Iterable<VariableDefinition> arguments) {
|
||||
return new MethodSyntaxElement.MethodSyntaxElementImpl(classname, "", body, arguments);
|
||||
static MethodSyntaxElement constructor(final String classname, final Closure body) {
|
||||
return new MethodSyntaxElement.MethodSyntaxElementImpl(
|
||||
classname, "", body,
|
||||
Collections.singletonList(ComputeStepSyntaxElement.CTOR_ARGUMENT)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.logstash.config.ir;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
|
@ -179,6 +180,38 @@ public final class CompiledPipelineTest extends RubyEnvTestCase {
|
|||
MatcherAssert.assertThat(testEvent.getEvent().getField("foo"), CoreMatchers.nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moreThan255Parents() throws Exception {
|
||||
final PipelineIR pipelineIR = ConfigCompiler.configToPipelineIR(
|
||||
"input {mockinput{}} filter { " +
|
||||
"if [foo] != \"bar\" { " +
|
||||
"mockfilter {} " +
|
||||
"mockaddfilter {} " +
|
||||
"if [foo] != \"bar\" { " +
|
||||
"mockfilter {} " +
|
||||
Strings.repeat("} else if [foo] != \"bar\" {" +
|
||||
"mockfilter {} ", 300) + " } } " +
|
||||
"} output {mockoutput{} }",
|
||||
false
|
||||
);
|
||||
final JrubyEventExtLibrary.RubyEvent testEvent =
|
||||
JrubyEventExtLibrary.RubyEvent.newRubyEvent(RubyUtil.RUBY, new Event());
|
||||
final Map<String, Supplier<IRubyObject>> filters = new HashMap<>();
|
||||
filters.put("mockfilter", () -> IDENTITY_FILTER);
|
||||
filters.put("mockaddfilter", () -> ADD_FIELD_FILTER);
|
||||
new CompiledPipeline(
|
||||
pipelineIR,
|
||||
new CompiledPipelineTest.MockPluginFactory(
|
||||
Collections.singletonMap("mockinput", () -> null),
|
||||
filters,
|
||||
Collections.singletonMap("mockoutput", mockOutputSupplier())
|
||||
)
|
||||
).buildExecution().compute(RubyUtil.RUBY.newArray(testEvent), false, false);
|
||||
final Collection<JrubyEventExtLibrary.RubyEvent> outputEvents = EVENT_SINKS.get(runId);
|
||||
MatcherAssert.assertThat(outputEvents.size(), CoreMatchers.is(1));
|
||||
MatcherAssert.assertThat(outputEvents.contains(testEvent), CoreMatchers.is(true));
|
||||
}
|
||||
|
||||
private Supplier<Consumer<Collection<JrubyEventExtLibrary.RubyEvent>>> mockOutputSupplier() {
|
||||
return () -> events -> events.forEach(
|
||||
event -> EVENT_SINKS.get(runId).add((JrubyEventExtLibrary.RubyEvent) event)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue