Cleanup and Refactoring of the transforms
* Split the transform into two constructs: `Transform` and `ExecutableTransform`. The former holds all the transform configuration, the latter can execute the transform based on that configuration (an executable transform holds a transform) - This makes the code clearer to understand and maintain. - This also enabled to pull some common implementation code into the `ExecutableTransform` and by that reduce the implementation details of each executable to the minimum required. * Also, extracted the `Transform.Parser` to its own top level class, and renamed it to - `TransformFactory`. The main thing that the factory does is: 1) delegate to the parsing to the `Transform` class, 2) construct & wire up the `ExecutableTransform`. * With the introduction of `Transform`, we no longer need the `SourceBuilder` for transforms. Instead, we have `Transform.Builder` that help you build a transform. This is much more intuitive from the client perspective. Original commit: elastic/x-pack-elasticsearch@f6ee0d0c75
This commit is contained in:
parent
34c9d6af62
commit
690af790b2
|
@ -11,6 +11,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
import org.elasticsearch.watcher.execution.Wid;
|
import org.elasticsearch.watcher.execution.Wid;
|
||||||
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
import org.elasticsearch.watcher.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.watcher.transform.TransformRegistry;
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
@ -23,14 +24,14 @@ import java.io.IOException;
|
||||||
public class ActionWrapper implements ToXContent {
|
public class ActionWrapper implements ToXContent {
|
||||||
|
|
||||||
private String id;
|
private String id;
|
||||||
private final @Nullable Transform transform;
|
private final @Nullable ExecutableTransform transform;
|
||||||
private final ExecutableAction action;
|
private final ExecutableAction action;
|
||||||
|
|
||||||
public ActionWrapper(String id, ExecutableAction action) {
|
public ActionWrapper(String id, ExecutableAction action) {
|
||||||
this(id, null, action);
|
this(id, null, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActionWrapper(String id, @Nullable Transform transform, ExecutableAction action) {
|
public ActionWrapper(String id, @Nullable ExecutableTransform transform, ExecutableAction action) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.transform = transform;
|
this.transform = transform;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
|
@ -40,7 +41,7 @@ public class ActionWrapper implements ToXContent {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transform transform() {
|
public ExecutableTransform transform() {
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ public class ActionWrapper implements ToXContent {
|
||||||
Payload payload = ctx.payload();
|
Payload payload = ctx.payload();
|
||||||
Transform.Result transformResult = null;
|
Transform.Result transformResult = null;
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
transformResult = transform.apply(ctx, payload);
|
transformResult = transform.execute(ctx, payload);
|
||||||
payload = transformResult.payload();
|
payload = transformResult.payload();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -84,7 +85,7 @@ public class ActionWrapper implements ToXContent {
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
builder.startObject(Transform.Parser.TRANSFORM_FIELD.getPreferredName())
|
builder.startObject(Transform.Field.TRANSFORM.getPreferredName())
|
||||||
.field(transform.type(), transform)
|
.field(transform.type(), transform)
|
||||||
.endObject();
|
.endObject();
|
||||||
}
|
}
|
||||||
|
@ -95,7 +96,7 @@ public class ActionWrapper implements ToXContent {
|
||||||
static ActionWrapper parse(String watchId, String actionId, XContentParser parser, ActionRegistry actionRegistry, TransformRegistry transformRegistry) throws IOException {
|
static ActionWrapper parse(String watchId, String actionId, XContentParser parser, ActionRegistry actionRegistry, TransformRegistry transformRegistry) throws IOException {
|
||||||
assert parser.currentToken() == XContentParser.Token.START_OBJECT;
|
assert parser.currentToken() == XContentParser.Token.START_OBJECT;
|
||||||
|
|
||||||
Transform transform = null;
|
ExecutableTransform transform = null;
|
||||||
ExecutableAction action = null;
|
ExecutableAction action = null;
|
||||||
|
|
||||||
String currentFieldName = null;
|
String currentFieldName = null;
|
||||||
|
@ -104,8 +105,8 @@ public class ActionWrapper implements ToXContent {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else {
|
} else {
|
||||||
if (Transform.Parser.TRANSFORM_FIELD.match(currentFieldName)) {
|
if (Transform.Field.TRANSFORM.match(currentFieldName)) {
|
||||||
transform = transformRegistry.parse(parser);
|
transform = transformRegistry.parse(watchId, parser);
|
||||||
} else {
|
} else {
|
||||||
// it's the type of the action
|
// it's the type of the action
|
||||||
ActionFactory actionFactory = actionRegistry.factory(currentFieldName);
|
ActionFactory actionFactory = actionRegistry.factory(currentFieldName);
|
||||||
|
@ -174,7 +175,7 @@ public class ActionWrapper implements ToXContent {
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
builder.startObject(Transform.Parser.TRANSFORM_RESULT_FIELD.getPreferredName())
|
builder.startObject(Transform.Field.TRANSFORM_RESULT.getPreferredName())
|
||||||
.field(transform.type(), transform)
|
.field(transform.type(), transform)
|
||||||
.endObject();
|
.endObject();
|
||||||
}
|
}
|
||||||
|
@ -194,8 +195,8 @@ public class ActionWrapper implements ToXContent {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
currentFieldName = parser.currentName();
|
currentFieldName = parser.currentName();
|
||||||
} else {
|
} else {
|
||||||
if (Transform.Parser.TRANSFORM_FIELD.match(currentFieldName)) {
|
if (Transform.Field.TRANSFORM.match(currentFieldName)) {
|
||||||
transformResult = transformRegistry.parseResult(parser);
|
transformResult = transformRegistry.parseResult(wid.watchId(), parser);
|
||||||
} else {
|
} else {
|
||||||
// it's the type of the action
|
// it's the type of the action
|
||||||
ActionFactory actionFactory = actionRegistry.factory(currentFieldName);
|
ActionFactory actionFactory = actionRegistry.factory(currentFieldName);
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class WatchSourceBuilder implements ToXContent {
|
||||||
private Trigger.SourceBuilder trigger;
|
private Trigger.SourceBuilder trigger;
|
||||||
private Input input = NoneInput.INSTANCE;
|
private Input input = NoneInput.INSTANCE;
|
||||||
private Condition condition = AlwaysCondition.INSTANCE;
|
private Condition condition = AlwaysCondition.INSTANCE;
|
||||||
private Transform.SourceBuilder transform = null;
|
private Transform transform = null;
|
||||||
private Map<String, TransformedAction> actions = new HashMap<>();
|
private Map<String, TransformedAction> actions = new HashMap<>();
|
||||||
private TimeValue throttlePeriod = null;
|
private TimeValue throttlePeriod = null;
|
||||||
private Map<String, Object> metadata;
|
private Map<String, Object> metadata;
|
||||||
|
@ -63,21 +63,25 @@ public class WatchSourceBuilder implements ToXContent {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WatchSourceBuilder transform(Transform.SourceBuilder transform) {
|
public WatchSourceBuilder transform(Transform transform) {
|
||||||
this.transform = transform;
|
this.transform = transform;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WatchSourceBuilder transform(Transform.Builder transform) {
|
||||||
|
return transform(transform.build());
|
||||||
|
}
|
||||||
|
|
||||||
public WatchSourceBuilder throttlePeriod(TimeValue throttlePeriod) {
|
public WatchSourceBuilder throttlePeriod(TimeValue throttlePeriod) {
|
||||||
this.throttlePeriod = throttlePeriod;
|
this.throttlePeriod = throttlePeriod;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public WatchSourceBuilder addAction(String id, Transform.SourceBuilder transform, Action action) {
|
public WatchSourceBuilder addAction(String id, Transform.Builder transform, Action action) {
|
||||||
actions.put(id, new TransformedAction(id, action, transform));
|
return addAction(id, transform.build(), action);
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public WatchSourceBuilder addAction(String id, Action action) {
|
public WatchSourceBuilder addAction(String id, Action action) {
|
||||||
actions.put(id, new TransformedAction(id, action));
|
actions.put(id, new TransformedAction(id, action));
|
||||||
return this;
|
return this;
|
||||||
|
@ -87,6 +91,16 @@ public class WatchSourceBuilder implements ToXContent {
|
||||||
return addAction(id, action.build());
|
return addAction(id, action.build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WatchSourceBuilder addAction(String id, Transform.Builder transform, Action.Builder action) {
|
||||||
|
actions.put(id, new TransformedAction(id, action.build(), transform.build()));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WatchSourceBuilder addAction(String id, Transform transform, Action action) {
|
||||||
|
actions.put(id, new TransformedAction(id, action, transform));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
public WatchSourceBuilder metadata(Map<String, Object> metadata) {
|
public WatchSourceBuilder metadata(Map<String, Object> metadata) {
|
||||||
this.metadata = metadata;
|
this.metadata = metadata;
|
||||||
return this;
|
return this;
|
||||||
|
@ -148,13 +162,13 @@ public class WatchSourceBuilder implements ToXContent {
|
||||||
|
|
||||||
private final String id;
|
private final String id;
|
||||||
private final Action action;
|
private final Action action;
|
||||||
private final @Nullable Transform.SourceBuilder transform;
|
private final @Nullable Transform transform;
|
||||||
|
|
||||||
public TransformedAction(String id, Action action) {
|
public TransformedAction(String id, Action action) {
|
||||||
this(id, action, null);
|
this(id, action, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransformedAction(String id, Action action, @Nullable Transform.SourceBuilder transform) {
|
public TransformedAction(String id, Action action, @Nullable Transform transform) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.transform = transform;
|
this.transform = transform;
|
||||||
this.action = action;
|
this.action = action;
|
||||||
|
@ -164,7 +178,7 @@ public class WatchSourceBuilder implements ToXContent {
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
builder.startObject(Transform.Parser.TRANSFORM_FIELD.getPreferredName())
|
builder.startObject(Transform.Field.TRANSFORM.getPreferredName())
|
||||||
.field(transform.type(), transform)
|
.field(transform.type(), transform)
|
||||||
.endObject();
|
.endObject();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.elasticsearch.watcher.input.Input;
|
||||||
import org.elasticsearch.watcher.support.Callback;
|
import org.elasticsearch.watcher.support.Callback;
|
||||||
import org.elasticsearch.watcher.support.clock.Clock;
|
import org.elasticsearch.watcher.support.clock.Clock;
|
||||||
import org.elasticsearch.watcher.throttle.Throttler;
|
import org.elasticsearch.watcher.throttle.Throttler;
|
||||||
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
import org.elasticsearch.watcher.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.watcher.trigger.TriggerEvent;
|
import org.elasticsearch.watcher.trigger.TriggerEvent;
|
||||||
import org.elasticsearch.watcher.watch.Watch;
|
import org.elasticsearch.watcher.watch.Watch;
|
||||||
|
@ -267,9 +268,9 @@ public class ExecutionService extends AbstractComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!throttleResult.throttle()) {
|
if (!throttleResult.throttle()) {
|
||||||
Transform transform = watch.transform();
|
ExecutableTransform transform = watch.transform();
|
||||||
if (transform != null) {
|
if (transform != null) {
|
||||||
Transform.Result result = watch.transform().apply(ctx, inputResult.payload());
|
Transform.Result result = watch.transform().execute(ctx, inputResult.payload());
|
||||||
ctx.onTransformResult(result);
|
ctx.onTransformResult(result);
|
||||||
}
|
}
|
||||||
for (ActionWrapper action : watch.actions()) {
|
for (ActionWrapper action : watch.actions()) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import org.elasticsearch.watcher.actions.ExecutableActions;
|
||||||
import org.elasticsearch.watcher.condition.Condition;
|
import org.elasticsearch.watcher.condition.Condition;
|
||||||
import org.elasticsearch.watcher.input.Input;
|
import org.elasticsearch.watcher.input.Input;
|
||||||
import org.elasticsearch.watcher.throttle.Throttler;
|
import org.elasticsearch.watcher.throttle.Throttler;
|
||||||
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
import org.elasticsearch.watcher.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.watcher.trigger.TriggerEvent;
|
import org.elasticsearch.watcher.trigger.TriggerEvent;
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
|
|
@ -7,7 +7,7 @@ package org.elasticsearch.watcher.support.init;
|
||||||
|
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||||
import org.elasticsearch.watcher.transform.ChainTransform;
|
import org.elasticsearch.watcher.transform.chain.ChainTransformFactory;
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.inject.multibindings.Multibinder;
|
import org.elasticsearch.common.inject.multibindings.Multibinder;
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public class InitializingModule extends AbstractModule {
|
||||||
Multibinder<InitializingService.Initializable> mbinder = Multibinder.newSetBinder(binder(), InitializingService.Initializable.class);
|
Multibinder<InitializingService.Initializable> mbinder = Multibinder.newSetBinder(binder(), InitializingService.Initializable.class);
|
||||||
mbinder.addBinding().to(ClientProxy.class);
|
mbinder.addBinding().to(ClientProxy.class);
|
||||||
mbinder.addBinding().to(ScriptServiceProxy.class);
|
mbinder.addBinding().to(ScriptServiceProxy.class);
|
||||||
mbinder.addBinding().to(ChainTransform.Parser.class);
|
mbinder.addBinding().to(ChainTransformFactory.class);
|
||||||
bind(InitializingService.class).asEagerSingleton();
|
bind(InitializingService.class).asEagerSingleton();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,231 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.watcher.transform;
|
|
||||||
|
|
||||||
import org.elasticsearch.watcher.WatcherSettingsException;
|
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
|
||||||
import org.elasticsearch.watcher.support.init.InitializingService;
|
|
||||||
import org.elasticsearch.common.ParseField;
|
|
||||||
import org.elasticsearch.common.collect.ImmutableList;
|
|
||||||
import org.elasticsearch.common.inject.Injector;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ChainTransform extends Transform<ChainTransform.Result> {
|
|
||||||
|
|
||||||
public static final String TYPE = "chain";
|
|
||||||
|
|
||||||
private final ImmutableList<Transform> transforms;
|
|
||||||
|
|
||||||
public ChainTransform(ImmutableList<Transform> transforms) {
|
|
||||||
this.transforms = transforms;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImmutableList<Transform> transforms() {
|
|
||||||
return transforms;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result apply(WatchExecutionContext ctx, Payload payload) throws IOException {
|
|
||||||
ImmutableList.Builder<Transform.Result> results = ImmutableList.builder();
|
|
||||||
for (Transform transform : transforms) {
|
|
||||||
Transform.Result result = transform.apply(ctx, payload);
|
|
||||||
results.add(result);
|
|
||||||
payload = result.payload();
|
|
||||||
}
|
|
||||||
return new Result(TYPE, payload, results.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
builder.startArray();
|
|
||||||
for (Transform transform : transforms) {
|
|
||||||
builder.startObject()
|
|
||||||
.field(transform.type(), transform)
|
|
||||||
.endObject();
|
|
||||||
}
|
|
||||||
return builder.endArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
ChainTransform transform = (ChainTransform) o;
|
|
||||||
|
|
||||||
if (!transforms.equals(transform.transforms)) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return transforms.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Result extends Transform.Result {
|
|
||||||
|
|
||||||
private final List<Transform.Result> results;
|
|
||||||
|
|
||||||
public Result(String type, Payload payload, List<Transform.Result> results) {
|
|
||||||
super(type, payload);
|
|
||||||
this.results = results;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected XContentBuilder xContentBody(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
builder.startArray(Parser.RESULTS_FIELD.getPreferredName());
|
|
||||||
for (Transform.Result result : results) {
|
|
||||||
builder.startObject()
|
|
||||||
.field(result.type(), result)
|
|
||||||
.endObject();
|
|
||||||
}
|
|
||||||
return builder.endArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Parser implements Transform.Parser<Result, ChainTransform>, InitializingService.Initializable {
|
|
||||||
|
|
||||||
public static final ParseField RESULTS_FIELD = new ParseField("results");
|
|
||||||
|
|
||||||
private TransformRegistry registry;
|
|
||||||
|
|
||||||
// used by guice
|
|
||||||
public Parser() {
|
|
||||||
}
|
|
||||||
|
|
||||||
// used for tests
|
|
||||||
Parser(TransformRegistry registry) {
|
|
||||||
this.registry = registry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void init(Injector injector) {
|
|
||||||
init(injector.getInstance(TransformRegistry.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(TransformRegistry registry) {
|
|
||||||
this.registry = registry;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ChainTransform parse(XContentParser parser) throws IOException {
|
|
||||||
XContentParser.Token token = parser.currentToken();
|
|
||||||
if (token != XContentParser.Token.START_ARRAY) {
|
|
||||||
throw new WatcherSettingsException("could not parse [chain] transform. expected an array of objects, but found [" + token + '}');
|
|
||||||
}
|
|
||||||
|
|
||||||
ImmutableList.Builder<Transform> builder = ImmutableList.builder();
|
|
||||||
|
|
||||||
String currentFieldName = null;
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
|
||||||
if (token != XContentParser.Token.START_OBJECT) {
|
|
||||||
throw new WatcherSettingsException("could not parse [chain] transform. expected a transform object, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
|
||||||
currentFieldName = parser.currentName();
|
|
||||||
} else if (token == XContentParser.Token.START_OBJECT) {
|
|
||||||
builder.add(registry.parse(currentFieldName, parser));
|
|
||||||
} else {
|
|
||||||
throw new WatcherSettingsException("could not parse [chain] transform. expected a transform object, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new ChainTransform(builder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result parseResult(XContentParser parser) throws IOException {
|
|
||||||
XContentParser.Token token = parser.currentToken();
|
|
||||||
if (token != XContentParser.Token.START_OBJECT) {
|
|
||||||
throw new TransformException("could not parse [chain] transform result. expected an object, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
|
|
||||||
Payload payload = null;
|
|
||||||
ImmutableList.Builder<Transform.Result> results = ImmutableList.builder();
|
|
||||||
|
|
||||||
String currentFieldName = null;
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
|
||||||
currentFieldName = parser.currentName();
|
|
||||||
} else {
|
|
||||||
if (token == XContentParser.Token.START_OBJECT) {
|
|
||||||
if (PAYLOAD_FIELD.match(currentFieldName)) {
|
|
||||||
payload = new Payload.XContent(parser);
|
|
||||||
} else {
|
|
||||||
throw new TransformException("could not parse [chain] transform result. unexpected object field [" + currentFieldName + "]");
|
|
||||||
}
|
|
||||||
} else if (token == XContentParser.Token.START_ARRAY) {
|
|
||||||
if (RESULTS_FIELD.match(currentFieldName)) {
|
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
|
||||||
if (token == XContentParser.Token.START_OBJECT) {
|
|
||||||
results.add(registry.parseResult(parser));
|
|
||||||
} else {
|
|
||||||
throw new TransformException("could not parse [chain] transform result. expected an object representing a transform result, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new TransformException("could not parse [chain] transform result. unexpected array field [" + currentFieldName + "]");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new TransformException("could not parse [chain] transform result. unexpected token [" + token+ "]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Result(TYPE, payload, results.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SourceBuilder implements Transform.SourceBuilder {
|
|
||||||
|
|
||||||
private final ImmutableList.Builder<Transform.SourceBuilder> builders = ImmutableList.builder();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourceBuilder(Transform.SourceBuilder... builders) {
|
|
||||||
this.builders.add(builders);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourceBuilder add(Transform.SourceBuilder builder) {
|
|
||||||
builders.add(builder);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
builder.startArray();
|
|
||||||
for (Transform.SourceBuilder transBuilder : builders.build()) {
|
|
||||||
builder.startObject()
|
|
||||||
.field(TYPE, transBuilder)
|
|
||||||
.endObject();
|
|
||||||
}
|
|
||||||
return builder.endArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class ExecutableTransform<T extends Transform, R extends Transform.Result> implements ToXContent {
|
||||||
|
|
||||||
|
protected final T transform;
|
||||||
|
protected final ESLogger logger;
|
||||||
|
|
||||||
|
public ExecutableTransform(T transform, ESLogger logger) {
|
||||||
|
this.transform = transform;
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String type() {
|
||||||
|
return transform.type();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T transform() {
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R execute(WatchExecutionContext ctx, Payload payload) throws IOException;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
return transform.toXContent(builder, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ExecutableTransform<?, ?> that = (ExecutableTransform<?, ?>) o;
|
||||||
|
|
||||||
|
return transform.equals(that.transform);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return transform.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,162 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.watcher.transform;
|
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
|
||||||
import org.elasticsearch.watcher.WatcherSettingsException;
|
|
||||||
import org.elasticsearch.watcher.support.Script;
|
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.elasticsearch.watcher.support.Variables.createCtxModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ScriptTransform extends Transform<ScriptTransform.Result> {
|
|
||||||
|
|
||||||
public static final String TYPE = "script";
|
|
||||||
|
|
||||||
private final ScriptServiceProxy scriptService;
|
|
||||||
private final Script script;
|
|
||||||
|
|
||||||
public ScriptTransform(ScriptServiceProxy scriptService, Script script) {
|
|
||||||
this.scriptService = scriptService;
|
|
||||||
this.script = script;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Script script() {
|
|
||||||
return script;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result apply(WatchExecutionContext ctx, Payload payload) throws IOException {
|
|
||||||
Map<String, Object> model = new HashMap<>();
|
|
||||||
model.putAll(script.params());
|
|
||||||
model.putAll(createCtxModel(ctx, payload));
|
|
||||||
ExecutableScript executable = scriptService.executable(script.lang(), script.script(), script.type(), model);
|
|
||||||
Object value = executable.run();
|
|
||||||
if (value instanceof Map) {
|
|
||||||
return new Result(TYPE, new Payload.Simple((Map<String, Object>) value));
|
|
||||||
}
|
|
||||||
Map<String, Object> data = new HashMap<>();
|
|
||||||
data.put("_value", value);
|
|
||||||
return new Result(TYPE, new Payload.Simple(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return builder.value(script);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
ScriptTransform transform = (ScriptTransform) o;
|
|
||||||
|
|
||||||
if (!script.equals(transform.script)) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return script.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Result extends Transform.Result {
|
|
||||||
|
|
||||||
public Result(String type, Payload payload) {
|
|
||||||
super(type, payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected XContentBuilder xContentBody(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Parser implements Transform.Parser<Result, ScriptTransform> {
|
|
||||||
|
|
||||||
private final ScriptServiceProxy scriptService;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public Parser(ScriptServiceProxy scriptService) {
|
|
||||||
this.scriptService = scriptService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ScriptTransform parse(XContentParser parser) throws IOException {
|
|
||||||
Script script = null;
|
|
||||||
try {
|
|
||||||
script = Script.parse(parser);
|
|
||||||
} catch (Script.ParseException pe) {
|
|
||||||
throw new WatcherSettingsException("could not parse [script] transform", pe);
|
|
||||||
}
|
|
||||||
return new ScriptTransform(scriptService, script);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result parseResult(XContentParser parser) throws IOException {
|
|
||||||
XContentParser.Token token = parser.currentToken();
|
|
||||||
if (token != XContentParser.Token.START_OBJECT) {
|
|
||||||
throw new TransformException("could not parse [script] transform result. expected an object, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
token = parser.nextToken();
|
|
||||||
if (token != XContentParser.Token.FIELD_NAME || !PAYLOAD_FIELD.match(parser.currentName())) {
|
|
||||||
throw new TransformException("could not parse [script] transform result. expected a payload field, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
token = parser.nextToken();
|
|
||||||
if (token != XContentParser.Token.START_OBJECT) {
|
|
||||||
throw new TransformException("could not parse [script] transform result. expected a payload object, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
return new Result(TYPE, new Payload.XContent(parser));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SourceBuilder implements Transform.SourceBuilder {
|
|
||||||
|
|
||||||
private final Script script;
|
|
||||||
|
|
||||||
public SourceBuilder(String script) {
|
|
||||||
this(new Script(script));
|
|
||||||
}
|
|
||||||
|
|
||||||
public SourceBuilder(Script script) {
|
|
||||||
this.script = script;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return script.toXContent(builder, params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,184 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.watcher.transform;
|
|
||||||
|
|
||||||
import org.elasticsearch.action.search.SearchRequest;
|
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
|
||||||
import org.elasticsearch.action.search.SearchType;
|
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
|
||||||
import org.elasticsearch.watcher.support.WatcherUtils;
|
|
||||||
import org.elasticsearch.watcher.support.SearchRequestEquivalence;
|
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
|
||||||
import org.elasticsearch.common.Strings;
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
|
||||||
import org.elasticsearch.common.collect.MapBuilder;
|
|
||||||
import org.elasticsearch.common.component.AbstractComponent;
|
|
||||||
import org.elasticsearch.common.inject.Inject;
|
|
||||||
import org.elasticsearch.common.logging.ESLogger;
|
|
||||||
import org.elasticsearch.common.settings.Settings;
|
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
|
||||||
import org.elasticsearch.script.ExecutableScript;
|
|
||||||
import org.elasticsearch.script.ScriptService;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static org.elasticsearch.watcher.support.WatcherUtils.flattenModel;
|
|
||||||
import static org.elasticsearch.watcher.support.Variables.createCtxModel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class SearchTransform extends Transform<SearchTransform.Result> {
|
|
||||||
|
|
||||||
public static final String TYPE = "search";
|
|
||||||
|
|
||||||
public static final SearchType DEFAULT_SEARCH_TYPE = SearchType.QUERY_THEN_FETCH;
|
|
||||||
|
|
||||||
protected final ESLogger logger;
|
|
||||||
protected final ScriptServiceProxy scriptService;
|
|
||||||
protected final ClientProxy client;
|
|
||||||
|
|
||||||
protected final SearchRequest request;
|
|
||||||
|
|
||||||
public SearchTransform(ESLogger logger, ScriptServiceProxy scriptService, ClientProxy client, SearchRequest request) {
|
|
||||||
this.logger = logger;
|
|
||||||
this.scriptService = scriptService;
|
|
||||||
this.client = client;
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result apply(WatchExecutionContext ctx, Payload payload) throws IOException {
|
|
||||||
SearchRequest req = createRequest(request, ctx, payload);
|
|
||||||
SearchResponse resp = client.search(req);
|
|
||||||
return new Result(TYPE, new Payload.XContent(resp));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException {
|
|
||||||
return WatcherUtils.writeSearchRequest(request, builder, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
|
||||||
|
|
||||||
SearchTransform transform = (SearchTransform) o;
|
|
||||||
|
|
||||||
if (!SearchRequestEquivalence.INSTANCE.equivalent(request, transform.request)) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return request.hashCode();
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchRequest createRequest(SearchRequest requestPrototype, WatchExecutionContext ctx, Payload payload) throws IOException {
|
|
||||||
SearchRequest request = new SearchRequest(requestPrototype)
|
|
||||||
.indicesOptions(requestPrototype.indicesOptions())
|
|
||||||
.indices(requestPrototype.indices());
|
|
||||||
if (Strings.hasLength(requestPrototype.source())) {
|
|
||||||
String requestSource = XContentHelper.convertToJson(requestPrototype.source(), false);
|
|
||||||
ExecutableScript script = scriptService.executable("mustache", requestSource, ScriptService.ScriptType.INLINE, createCtxModel(ctx, payload));
|
|
||||||
request.source((BytesReference) script.unwrap(script.run()), false);
|
|
||||||
} else if (requestPrototype.templateName() != null) {
|
|
||||||
MapBuilder<String, Object> templateParams = MapBuilder.newMapBuilder(requestPrototype.templateParams())
|
|
||||||
.putAll(flattenModel(createCtxModel(ctx, payload)));
|
|
||||||
request.templateParams(templateParams.map());
|
|
||||||
request.templateName(requestPrototype.templateName());
|
|
||||||
request.templateType(requestPrototype.templateType());
|
|
||||||
} else {
|
|
||||||
throw new TransformException("search requests needs either source or template name");
|
|
||||||
}
|
|
||||||
return request;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Result extends Transform.Result {
|
|
||||||
|
|
||||||
public Result(String type, Payload payload) {
|
|
||||||
super(type, payload);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected XContentBuilder xContentBody(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return builder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Parser extends AbstractComponent implements Transform.Parser<Result, SearchTransform> {
|
|
||||||
|
|
||||||
protected final ScriptServiceProxy scriptService;
|
|
||||||
protected final ClientProxy client;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public Parser(Settings settings, ScriptServiceProxy scriptService, ClientProxy client) {
|
|
||||||
super(settings);
|
|
||||||
this.scriptService = scriptService;
|
|
||||||
this.client = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SearchTransform parse(XContentParser parser) throws IOException {
|
|
||||||
SearchRequest request = WatcherUtils.readSearchRequest(parser, DEFAULT_SEARCH_TYPE);
|
|
||||||
return new SearchTransform(logger, scriptService, client, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result parseResult(XContentParser parser) throws IOException {
|
|
||||||
XContentParser.Token token = parser.currentToken();
|
|
||||||
if (token != XContentParser.Token.START_OBJECT) {
|
|
||||||
throw new TransformException("could not parse [search] transform result. expected an object, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
token = parser.nextToken();
|
|
||||||
if (token != XContentParser.Token.FIELD_NAME || !PAYLOAD_FIELD.match(parser.currentName())) {
|
|
||||||
throw new TransformException("could not parse [search] transform result. expected a payload field, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
token = parser.nextToken();
|
|
||||||
if (token != XContentParser.Token.START_OBJECT) {
|
|
||||||
throw new TransformException("could not parse [search] transform result. expected a payload object, but found [" + token + "]");
|
|
||||||
}
|
|
||||||
return new Result(TYPE, new Payload.XContent(parser));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class SourceBuilder implements Transform.SourceBuilder {
|
|
||||||
|
|
||||||
private final SearchRequest request;
|
|
||||||
|
|
||||||
public SourceBuilder(SearchRequest request) {
|
|
||||||
this.request = request;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String type() {
|
|
||||||
return TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return WatcherUtils.writeSearchRequest(request, builder, params);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,25 +5,21 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.watcher.transform;
|
package org.elasticsearch.watcher.transform;
|
||||||
|
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
|
||||||
import org.elasticsearch.common.ParseField;
|
import org.elasticsearch.common.ParseField;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class Transform<R extends Transform.Result> implements ToXContent {
|
public interface Transform extends ToXContent {
|
||||||
|
|
||||||
public abstract String type();
|
String type();
|
||||||
|
|
||||||
public abstract Result apply(WatchExecutionContext ctx, Payload payload) throws IOException;
|
abstract class Result implements ToXContent {
|
||||||
|
|
||||||
public static abstract class Result implements ToXContent {
|
|
||||||
|
|
||||||
protected final String type;
|
protected final String type;
|
||||||
protected final Payload payload;
|
protected final Payload payload;
|
||||||
|
@ -44,7 +40,7 @@ public abstract class Transform<R extends Transform.Result> implements ToXConten
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
builder.field(Parser.PAYLOAD_FIELD.getPreferredName(), payload);
|
builder.field(Field.PAYLOAD.getPreferredName(), payload);
|
||||||
xContentBody(builder, params);
|
xContentBody(builder, params);
|
||||||
return builder.endObject();
|
return builder.endObject();
|
||||||
}
|
}
|
||||||
|
@ -53,23 +49,14 @@ public abstract class Transform<R extends Transform.Result> implements ToXConten
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface Parser<R extends Transform.Result, T extends Transform<R>> {
|
interface Builder<T extends Transform> {
|
||||||
|
|
||||||
public static final ParseField PAYLOAD_FIELD = new ParseField("payload");
|
|
||||||
public static final ParseField TRANSFORM_FIELD = new ParseField("transform");
|
|
||||||
public static final ParseField TRANSFORM_RESULT_FIELD = new ParseField("transform_result");
|
|
||||||
|
|
||||||
String type();
|
|
||||||
|
|
||||||
T parse(XContentParser parser) throws IOException;
|
|
||||||
|
|
||||||
R parseResult(XContentParser parser) throws IOException;
|
|
||||||
|
|
||||||
|
T build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static interface SourceBuilder extends ToXContent {
|
interface Field {
|
||||||
|
ParseField PAYLOAD = new ParseField("payload");
|
||||||
String type();
|
ParseField TRANSFORM = new ParseField("transform");
|
||||||
|
ParseField TRANSFORM_RESULT = new ParseField("transform_result");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,11 @@
|
||||||
package org.elasticsearch.watcher.transform;
|
package org.elasticsearch.watcher.transform;
|
||||||
|
|
||||||
import org.elasticsearch.action.search.SearchRequest;
|
import org.elasticsearch.action.search.SearchRequest;
|
||||||
|
import org.elasticsearch.action.search.SearchRequestBuilder;
|
||||||
import org.elasticsearch.watcher.support.Script;
|
import org.elasticsearch.watcher.support.Script;
|
||||||
|
import org.elasticsearch.watcher.transform.chain.ChainTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.script.ScriptTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.search.SearchTransform;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -16,20 +20,28 @@ public final class TransformBuilders {
|
||||||
private TransformBuilders() {
|
private TransformBuilders() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SearchTransform.SourceBuilder searchTransform(SearchRequest request) {
|
public static SearchTransform.Builder searchTransform(SearchRequest request) {
|
||||||
return new SearchTransform.SourceBuilder(request);
|
return SearchTransform.builder(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ScriptTransform.SourceBuilder scriptTransform(String script) {
|
public static SearchTransform.Builder searchTransform(SearchRequestBuilder request) {
|
||||||
return new ScriptTransform.SourceBuilder(script);
|
return searchTransform(request.request());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ScriptTransform.SourceBuilder scriptTransform(Script script) {
|
public static ScriptTransform.Builder scriptTransform(String script) {
|
||||||
return new ScriptTransform.SourceBuilder(script);
|
return scriptTransform(new Script(script));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChainTransform.SourceBuilder chainTransform(Transform.SourceBuilder... transforms) {
|
public static ScriptTransform.Builder scriptTransform(Script script) {
|
||||||
return new ChainTransform.SourceBuilder(transforms);
|
return ScriptTransform.builder(script);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChainTransform.Builder chainTransform(Transform.Builder... transforms) {
|
||||||
|
return ChainTransform.builder().add(transforms);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChainTransform.Builder chainTransform(Transform... transforms) {
|
||||||
|
return ChainTransform.builder(transforms);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,11 @@ import org.elasticsearch.watcher.WatcherException;
|
||||||
*/
|
*/
|
||||||
public class TransformException extends WatcherException {
|
public class TransformException extends WatcherException {
|
||||||
|
|
||||||
public TransformException(String msg) {
|
public TransformException(String msg, Object... args) {
|
||||||
super(msg);
|
super(msg, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransformException(String msg, Throwable cause) {
|
public TransformException(String msg, Throwable cause, Object... args) {
|
||||||
super(msg, cause);
|
super(msg, cause, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class TransformFactory<T extends Transform, R extends Transform.Result, E extends ExecutableTransform<T, R>> {
|
||||||
|
|
||||||
|
protected final ESLogger transformLogger;
|
||||||
|
|
||||||
|
public TransformFactory(ESLogger transformLogger) {
|
||||||
|
this.transformLogger = transformLogger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The type of the transform
|
||||||
|
*/
|
||||||
|
public abstract String type();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given xcontent and creates a concrete transform
|
||||||
|
*/
|
||||||
|
public abstract T parseTransform(String watchId, XContentParser parser) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given xcontent and creates a concrete transform result
|
||||||
|
*/
|
||||||
|
public abstract R parseResult(String watchId, XContentParser parser) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an executable transform out of the given transform.
|
||||||
|
*/
|
||||||
|
public abstract E createExecutable(T transform);
|
||||||
|
|
||||||
|
public E parseExecutable(String watchId, XContentParser parser) throws IOException {
|
||||||
|
T transform = parseTransform(watchId, parser);
|
||||||
|
return createExecutable(transform);
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,12 @@ package org.elasticsearch.watcher.transform;
|
||||||
|
|
||||||
import org.elasticsearch.common.inject.AbstractModule;
|
import org.elasticsearch.common.inject.AbstractModule;
|
||||||
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
import org.elasticsearch.common.inject.multibindings.MapBinder;
|
||||||
|
import org.elasticsearch.watcher.transform.chain.ChainTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.chain.ChainTransformFactory;
|
||||||
|
import org.elasticsearch.watcher.transform.script.ScriptTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.script.ScriptTransformFactory;
|
||||||
|
import org.elasticsearch.watcher.transform.search.SearchTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.search.SearchTransformFactory;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -16,24 +22,26 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public class TransformModule extends AbstractModule {
|
public class TransformModule extends AbstractModule {
|
||||||
|
|
||||||
private Map<String, Class<? extends Transform.Parser>> parsers = new HashMap<>();
|
private Map<String, Class<? extends TransformFactory>> factories = new HashMap<>();
|
||||||
|
|
||||||
public void registerPayload(String payloadType, Class<? extends Transform.Parser> parserType) {
|
public void registerTransform(String payloadType, Class<? extends TransformFactory> parserType) {
|
||||||
parsers.put(payloadType, parserType);
|
factories.put(payloadType, parserType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
|
MapBinder<String, TransformFactory> mbinder = MapBinder.newMapBinder(binder(), String.class, TransformFactory.class);
|
||||||
|
|
||||||
MapBinder<String, Transform.Parser> mbinder = MapBinder.newMapBinder(binder(), String.class, Transform.Parser.class);
|
bind(SearchTransformFactory.class).asEagerSingleton();
|
||||||
bind(SearchTransform.Parser.class).asEagerSingleton();
|
mbinder.addBinding(SearchTransform.TYPE).to(SearchTransformFactory.class);
|
||||||
mbinder.addBinding(SearchTransform.TYPE).to(SearchTransform.Parser.class);
|
|
||||||
bind(ScriptTransform.Parser.class).asEagerSingleton();
|
|
||||||
mbinder.addBinding(ScriptTransform.TYPE).to(ScriptTransform.Parser.class);
|
|
||||||
bind(ChainTransform.Parser.class).asEagerSingleton();
|
|
||||||
mbinder.addBinding(ChainTransform.TYPE).to(ChainTransform.Parser.class);
|
|
||||||
|
|
||||||
for (Map.Entry<String, Class<? extends Transform.Parser>> entry : parsers.entrySet()) {
|
bind(ScriptTransformFactory.class).asEagerSingleton();
|
||||||
|
mbinder.addBinding(ScriptTransform.TYPE).to(ScriptTransformFactory.class);
|
||||||
|
|
||||||
|
bind(ChainTransformFactory.class).asEagerSingleton();
|
||||||
|
mbinder.addBinding(ChainTransform.TYPE).to(ChainTransformFactory.class);
|
||||||
|
|
||||||
|
for (Map.Entry<String, Class<? extends TransformFactory>> entry : factories.entrySet()) {
|
||||||
bind(entry.getValue()).asEagerSingleton();
|
bind(entry.getValue()).asEagerSingleton();
|
||||||
mbinder.addBinding(entry.getKey()).to(entry.getValue());
|
mbinder.addBinding(entry.getKey()).to(entry.getValue());
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.watcher.transform;
|
package org.elasticsearch.watcher.transform;
|
||||||
|
|
||||||
import org.elasticsearch.watcher.WatcherSettingsException;
|
|
||||||
import org.elasticsearch.common.collect.ImmutableMap;
|
import org.elasticsearch.common.collect.ImmutableMap;
|
||||||
import org.elasticsearch.common.inject.Inject;
|
import org.elasticsearch.common.inject.Inject;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
@ -18,36 +17,48 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
public class TransformRegistry {
|
public class TransformRegistry {
|
||||||
|
|
||||||
private final ImmutableMap<String, Transform.Parser> parsers;
|
private final ImmutableMap<String, TransformFactory> factories;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public TransformRegistry(Map<String, Transform.Parser> parsers) {
|
public TransformRegistry(Map<String, TransformFactory> factories) {
|
||||||
this.parsers = ImmutableMap.copyOf(parsers);
|
this.factories = ImmutableMap.copyOf(factories);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transform parse(XContentParser parser) throws IOException {
|
public TransformFactory factory(String type) {
|
||||||
|
return factories.get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExecutableTransform parse(String watchId, XContentParser parser) throws IOException {
|
||||||
String type = null;
|
String type = null;
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
Transform transform = null;
|
ExecutableTransform transform = null;
|
||||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
type = parser.currentName();
|
type = parser.currentName();
|
||||||
} else if (type != null) {
|
} else if (type != null) {
|
||||||
transform = parse(type, parser);
|
transform = parse(watchId, type, parser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transform parse(String type, XContentParser parser) throws IOException {
|
public ExecutableTransform parse(String watchId, String type, XContentParser parser) throws IOException {
|
||||||
Transform.Parser transformParser = parsers.get(type);
|
TransformFactory factory = factories.get(type);
|
||||||
if (transformParser == null) {
|
if (factory == null) {
|
||||||
throw new WatcherSettingsException("unknown transform type [" + type + "]");
|
throw new TransformException("could not parse transform for watch [{}], unknown transform type [{}]", watchId, type);
|
||||||
}
|
}
|
||||||
return transformParser.parse(parser);
|
return factory.parseExecutable(watchId, parser);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transform.Result parseResult(XContentParser parser) throws IOException {
|
public Transform parseTransform(String watchId, String type, XContentParser parser) throws IOException {
|
||||||
|
TransformFactory factory = factories.get(type);
|
||||||
|
if (factory == null) {
|
||||||
|
throw new TransformException("could not parse transform for watch [{}], unknown transform type [{}]", watchId, type);
|
||||||
|
}
|
||||||
|
return factory.parseTransform(watchId, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Transform.Result parseResult(String watchId, XContentParser parser) throws IOException {
|
||||||
String type = null;
|
String type = null;
|
||||||
XContentParser.Token token;
|
XContentParser.Token token;
|
||||||
Transform.Result result = null;
|
Transform.Result result = null;
|
||||||
|
@ -55,17 +66,17 @@ public class TransformRegistry {
|
||||||
if (token == XContentParser.Token.FIELD_NAME) {
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
type = parser.currentName();
|
type = parser.currentName();
|
||||||
} else if (type != null) {
|
} else if (type != null) {
|
||||||
result = parseResult(type, parser);
|
result = parseResult(watchId, type, parser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transform.Result parseResult(String type, XContentParser parser) throws IOException {
|
public Transform.Result parseResult(String watchId, String type, XContentParser parser) throws IOException {
|
||||||
Transform.Parser transformParser = parsers.get(type);
|
TransformFactory factory = factories.get(type);
|
||||||
if (transformParser == null) {
|
if (factory == null) {
|
||||||
throw new TransformException("unknown transform type [" + type + "]");
|
throw new TransformException("could not parse transform result for watch [{}]. unknown transform type [{}]", watchId, type);
|
||||||
}
|
}
|
||||||
return transformParser.parseResult(parser);
|
return factory.parseResult(watchId, parser);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,190 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.chain;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.ParseField;
|
||||||
|
import org.elasticsearch.common.collect.ImmutableList;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ChainTransform implements Transform {
|
||||||
|
|
||||||
|
public static final String TYPE = "chain";
|
||||||
|
|
||||||
|
private final ImmutableList<Transform> transforms;
|
||||||
|
|
||||||
|
public ChainTransform(ImmutableList<Transform> transforms) {
|
||||||
|
this.transforms = transforms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmutableList<Transform> getTransforms() {
|
||||||
|
return transforms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ChainTransform that = (ChainTransform) o;
|
||||||
|
|
||||||
|
return transforms.equals(that.transforms);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return transforms.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
builder.startArray();
|
||||||
|
for (Transform transform : transforms) {
|
||||||
|
builder.startObject()
|
||||||
|
.field(transform.type(), transform)
|
||||||
|
.endObject();
|
||||||
|
}
|
||||||
|
return builder.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ChainTransform parse(String watchId, XContentParser parser, TransformRegistry transformRegistry) throws IOException {
|
||||||
|
XContentParser.Token token = parser.currentToken();
|
||||||
|
if (token != XContentParser.Token.START_ARRAY) {
|
||||||
|
throw new ChainTransformException("could not parse [{}] transform for watch [{}]. expected an array of transform objects, but found [{}] instead", TYPE, watchId, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImmutableList.Builder<Transform> builder = ImmutableList.builder();
|
||||||
|
|
||||||
|
String currentFieldName = null;
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
|
if (token != XContentParser.Token.START_OBJECT) {
|
||||||
|
throw new ChainTransformException("could not parse [{}] transform for watch [{}]. expected a transform object, but found [{}] instead", TYPE, watchId, token);
|
||||||
|
}
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
currentFieldName = parser.currentName();
|
||||||
|
} else if (token == XContentParser.Token.START_OBJECT) {
|
||||||
|
builder.add(transformRegistry.parseTransform(watchId, currentFieldName, parser));
|
||||||
|
} else {
|
||||||
|
throw new ChainTransformException("could not parse [{}] transform for watch [{}]. expected a transform object, but found [{}] instead", TYPE, watchId, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ChainTransform(builder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder(Transform... transforms) {
|
||||||
|
return new Builder(transforms);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Result extends Transform.Result {
|
||||||
|
|
||||||
|
private final ImmutableList<Transform.Result> results;
|
||||||
|
|
||||||
|
public Result(Payload payload, ImmutableList<Transform.Result> results) {
|
||||||
|
super(TYPE, payload);
|
||||||
|
this.results = results;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmutableList<Transform.Result> results() {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected XContentBuilder xContentBody(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
builder.startArray(Field.RESULTS.getPreferredName());
|
||||||
|
for (Transform.Result result : results) {
|
||||||
|
builder.startObject()
|
||||||
|
.field(result.type(), result)
|
||||||
|
.endObject();
|
||||||
|
}
|
||||||
|
return builder.endArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result parse(String watchId, XContentParser parser, TransformRegistry transformRegistry) throws IOException {
|
||||||
|
XContentParser.Token token = parser.currentToken();
|
||||||
|
if (token != XContentParser.Token.START_OBJECT) {
|
||||||
|
throw new ChainTransformException("could not parse [{}] transform result for watch [{}]. expected an object, but found [{}] instead", TYPE, watchId, token);
|
||||||
|
}
|
||||||
|
|
||||||
|
Payload payload = null;
|
||||||
|
ImmutableList.Builder<Transform.Result> results = ImmutableList.builder();
|
||||||
|
|
||||||
|
String currentFieldName = null;
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||||
|
if (token == XContentParser.Token.FIELD_NAME) {
|
||||||
|
currentFieldName = parser.currentName();
|
||||||
|
} else {
|
||||||
|
if (token == XContentParser.Token.START_OBJECT) {
|
||||||
|
if (Field.PAYLOAD.match(currentFieldName)) {
|
||||||
|
payload = new Payload.XContent(parser);
|
||||||
|
} else {
|
||||||
|
throw new ChainTransformException("could not parse [{}] transform result for watch [{}]. unexpected object field [{}]", TYPE, watchId, currentFieldName);
|
||||||
|
}
|
||||||
|
} else if (token == XContentParser.Token.START_ARRAY) {
|
||||||
|
if (Field.RESULTS.match(currentFieldName)) {
|
||||||
|
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||||
|
if (token == XContentParser.Token.START_OBJECT) {
|
||||||
|
results.add(transformRegistry.parseResult(watchId, parser));
|
||||||
|
} else {
|
||||||
|
throw new ChainTransformException("could not parse [{}] transform result for watch [{}]. expected an object representing a transform result, but found [{}] instead", TYPE, watchId, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new ChainTransformException("could not parse [{}] transform result for watch [{}]. unexpected array field [{}]", TYPE, watchId, currentFieldName);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new ChainTransformException("could not parse [{}] transform result for watch [{}]. unexpected token [{}]", TYPE, watchId, token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ChainTransform.Result(payload, results.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder implements Transform.Builder<ChainTransform> {
|
||||||
|
|
||||||
|
private final ImmutableList.Builder<Transform> transforms = ImmutableList.builder();
|
||||||
|
|
||||||
|
public Builder(Transform... transforms) {
|
||||||
|
this.transforms.add(transforms);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder add(Transform... transforms) {
|
||||||
|
this.transforms.add(transforms);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder add(Transform.Builder... transforms) {
|
||||||
|
for (Transform.Builder transform: transforms) {
|
||||||
|
this.transforms.add(transform.build());
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChainTransform build() {
|
||||||
|
return new ChainTransform(transforms.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Field extends Transform.Field {
|
||||||
|
ParseField RESULTS = new ParseField("results");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.chain;
|
||||||
|
|
||||||
|
import org.elasticsearch.watcher.transform.TransformException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ChainTransformException extends TransformException {
|
||||||
|
|
||||||
|
public ChainTransformException(String msg, Object... args) {
|
||||||
|
super(msg, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChainTransformException(String msg, Throwable cause, Object... args) {
|
||||||
|
super(msg, cause, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.chain;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.collect.ImmutableList;
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.inject.Injector;
|
||||||
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.watcher.support.init.InitializingService;
|
||||||
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformFactory;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ChainTransformFactory extends TransformFactory<ChainTransform, ChainTransform.Result, ExecutableChainTransform> implements InitializingService.Initializable {
|
||||||
|
|
||||||
|
private TransformRegistry registry;
|
||||||
|
|
||||||
|
// used by guice
|
||||||
|
public ChainTransformFactory(Settings settings) {
|
||||||
|
super(Loggers.getLogger(ExecutableChainTransform.class, settings));
|
||||||
|
}
|
||||||
|
|
||||||
|
// used for tests
|
||||||
|
public ChainTransformFactory(TransformRegistry registry) {
|
||||||
|
super(Loggers.getLogger(ExecutableChainTransform.class));
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// used for tests
|
||||||
|
public ChainTransformFactory() {
|
||||||
|
super(Loggers.getLogger(ExecutableChainTransform.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(Injector injector) {
|
||||||
|
init(injector.getInstance(TransformRegistry.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void init(TransformRegistry registry) {
|
||||||
|
this.registry = registry;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return ChainTransform.TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChainTransform parseTransform(String watchId, XContentParser parser) throws IOException {
|
||||||
|
return ChainTransform.parse(watchId, parser, registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChainTransform.Result parseResult(String watchId, XContentParser parser) throws IOException {
|
||||||
|
return ChainTransform.Result.parse(watchId, parser, registry);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecutableChainTransform createExecutable(ChainTransform chainTransform) {
|
||||||
|
ImmutableList.Builder<ExecutableTransform> executables = ImmutableList.builder();
|
||||||
|
for (Transform transform : chainTransform.getTransforms()) {
|
||||||
|
TransformFactory factory = registry.factory(transform.type());
|
||||||
|
executables.add(factory.createExecutable(transform));
|
||||||
|
}
|
||||||
|
return new ExecutableChainTransform(chainTransform, transformLogger, executables.build());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.chain;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.collect.ImmutableList;
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ExecutableChainTransform extends ExecutableTransform<ChainTransform, ChainTransform.Result> {
|
||||||
|
|
||||||
|
private final ImmutableList<ExecutableTransform> transforms;
|
||||||
|
|
||||||
|
public ExecutableChainTransform(ChainTransform transform, ESLogger logger, ImmutableList<ExecutableTransform> transforms) {
|
||||||
|
super(transform, logger);
|
||||||
|
this.transforms = transforms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImmutableList<ExecutableTransform> executableTransforms() {
|
||||||
|
return transforms;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChainTransform.Result execute(WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
|
ImmutableList.Builder<Transform.Result> results = ImmutableList.builder();
|
||||||
|
for (ExecutableTransform transform : transforms) {
|
||||||
|
Transform.Result result = transform.execute(ctx, payload);
|
||||||
|
results.add(result);
|
||||||
|
payload = result.payload();
|
||||||
|
}
|
||||||
|
return new ChainTransform.Result(payload, results.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.script;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
|
import org.elasticsearch.watcher.support.Script;
|
||||||
|
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||||
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static org.elasticsearch.watcher.support.Variables.createCtxModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ExecutableScriptTransform extends ExecutableTransform<ScriptTransform, ScriptTransform.Result> {
|
||||||
|
|
||||||
|
private final ScriptServiceProxy scriptService;
|
||||||
|
|
||||||
|
public ExecutableScriptTransform(ScriptTransform transform, ESLogger logger, ScriptServiceProxy scriptService) {
|
||||||
|
super(transform, logger);
|
||||||
|
this.scriptService = scriptService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScriptTransform.Result execute(WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
|
Script script = transform.getScript();
|
||||||
|
Map<String, Object> model = new HashMap<>();
|
||||||
|
model.putAll(script.params());
|
||||||
|
model.putAll(createCtxModel(ctx, payload));
|
||||||
|
ExecutableScript executable = scriptService.executable(script.lang(), script.script(), script.type(), model);
|
||||||
|
Object value = executable.run();
|
||||||
|
if (value instanceof Map) {
|
||||||
|
return new ScriptTransform.Result(new Payload.Simple((Map<String, Object>) value));
|
||||||
|
}
|
||||||
|
Map<String, Object> data = new HashMap<>();
|
||||||
|
data.put("_value", value);
|
||||||
|
return new ScriptTransform.Result(new Payload.Simple(data));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.script;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.watcher.support.Script;
|
||||||
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ScriptTransform implements Transform {
|
||||||
|
|
||||||
|
public static final String TYPE = "script";
|
||||||
|
|
||||||
|
private final Script script;
|
||||||
|
|
||||||
|
public ScriptTransform(Script script) {
|
||||||
|
this.script = script;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Script getScript() {
|
||||||
|
return script;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
ScriptTransform that = (ScriptTransform) o;
|
||||||
|
|
||||||
|
return script.equals(that.script);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return script.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
return script.toXContent(builder, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ScriptTransform parse(String watchId, XContentParser parser) throws IOException {
|
||||||
|
try {
|
||||||
|
Script script = Script.parse(parser);
|
||||||
|
return new ScriptTransform(script);
|
||||||
|
} catch (Script.ParseException pe) {
|
||||||
|
throw new ScriptTransformException("could not parse [{}] transform for watch [{}]. failed to parse script", pe, TYPE, watchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder(Script script) {
|
||||||
|
return new Builder(script);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Result extends Transform.Result {
|
||||||
|
|
||||||
|
public Result(Payload payload) {
|
||||||
|
super(TYPE, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected XContentBuilder xContentBody(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result parse(String watchId, XContentParser parser) throws IOException {
|
||||||
|
XContentParser.Token token = parser.currentToken();
|
||||||
|
if (token != XContentParser.Token.START_OBJECT) {
|
||||||
|
throw new ScriptTransformException("could not parse [{}] transform result for watch [{}]. expected an object, but found [{}] instead", TYPE, watchId, token);
|
||||||
|
}
|
||||||
|
token = parser.nextToken();
|
||||||
|
if (token != XContentParser.Token.FIELD_NAME || !Field.PAYLOAD.match(parser.currentName())) {
|
||||||
|
throw new ScriptTransformException("could not parse [{}] transform result for watch [{}]. expected a [{}] object, but found [{}] instead", TYPE, watchId, Field.PAYLOAD.getPreferredName(), token);
|
||||||
|
}
|
||||||
|
token = parser.nextToken();
|
||||||
|
if (token != XContentParser.Token.START_OBJECT) {
|
||||||
|
throw new ScriptTransformException("could not parse [{}] transform result for watch [{}]. expected a [{}] object, but found [{}] instead", TYPE, watchId, Field.PAYLOAD.getPreferredName(), token);
|
||||||
|
}
|
||||||
|
return new ScriptTransform.Result(new Payload.XContent(parser));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder implements Transform.Builder<ScriptTransform> {
|
||||||
|
|
||||||
|
private final Script script;
|
||||||
|
|
||||||
|
public Builder(Script script) {
|
||||||
|
this.script = script;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScriptTransform build() {
|
||||||
|
return new ScriptTransform(script);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.script;
|
||||||
|
|
||||||
|
import org.elasticsearch.watcher.transform.TransformException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ScriptTransformException extends TransformException {
|
||||||
|
|
||||||
|
public ScriptTransformException(String msg, Object... args) {
|
||||||
|
super(msg, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ScriptTransformException(String msg, Throwable cause, Object... args) {
|
||||||
|
super(msg, cause, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.script;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ScriptTransformFactory extends TransformFactory<ScriptTransform, ScriptTransform.Result, ExecutableScriptTransform> {
|
||||||
|
|
||||||
|
private final ScriptServiceProxy scriptService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public ScriptTransformFactory(Settings settings, ScriptServiceProxy scriptService) {
|
||||||
|
super(Loggers.getLogger(ExecutableScriptTransform.class, settings));
|
||||||
|
this.scriptService = scriptService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return ScriptTransform.TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScriptTransform parseTransform(String watchId, XContentParser parser) throws IOException {
|
||||||
|
return ScriptTransform.parse(watchId, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScriptTransform.Result parseResult(String watchId, XContentParser parser) throws IOException {
|
||||||
|
return ScriptTransform.Result.parse(watchId, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecutableScriptTransform createExecutable(ScriptTransform transform) {
|
||||||
|
return new ExecutableScriptTransform(transform, transformLogger, scriptService);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.search;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.search.SearchRequest;
|
||||||
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
|
import org.elasticsearch.action.search.SearchType;
|
||||||
|
import org.elasticsearch.common.Strings;
|
||||||
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
|
import org.elasticsearch.common.collect.MapBuilder;
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
|
import org.elasticsearch.script.ExecutableScript;
|
||||||
|
import org.elasticsearch.script.ScriptService;
|
||||||
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
|
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||||
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformException;
|
||||||
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static org.elasticsearch.watcher.support.Variables.createCtxModel;
|
||||||
|
import static org.elasticsearch.watcher.support.WatcherUtils.flattenModel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ExecutableSearchTransform extends ExecutableTransform<SearchTransform, SearchTransform.Result> {
|
||||||
|
|
||||||
|
public static final SearchType DEFAULT_SEARCH_TYPE = SearchType.QUERY_THEN_FETCH;
|
||||||
|
|
||||||
|
protected final ScriptServiceProxy scriptService;
|
||||||
|
protected final ClientProxy client;
|
||||||
|
|
||||||
|
public ExecutableSearchTransform(SearchTransform transform, ESLogger logger, ScriptServiceProxy scriptService, ClientProxy client) {
|
||||||
|
super(transform, logger);
|
||||||
|
this.scriptService = scriptService;
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SearchTransform.Result execute(WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
|
SearchRequest req = createRequest(transform.request, ctx, payload);
|
||||||
|
SearchResponse resp = client.search(req);
|
||||||
|
return new SearchTransform.Result(new Payload.XContent(resp));
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchRequest createRequest(SearchRequest requestPrototype, WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
|
SearchRequest request = new SearchRequest(requestPrototype)
|
||||||
|
.indicesOptions(requestPrototype.indicesOptions())
|
||||||
|
.indices(requestPrototype.indices());
|
||||||
|
if (Strings.hasLength(requestPrototype.source())) {
|
||||||
|
String requestSource = XContentHelper.convertToJson(requestPrototype.source(), false);
|
||||||
|
ExecutableScript script = scriptService.executable("mustache", requestSource, ScriptService.ScriptType.INLINE, createCtxModel(ctx, payload));
|
||||||
|
request.source((BytesReference) script.unwrap(script.run()), false);
|
||||||
|
} else if (requestPrototype.templateName() != null) {
|
||||||
|
MapBuilder<String, Object> templateParams = MapBuilder.newMapBuilder(requestPrototype.templateParams())
|
||||||
|
.putAll(flattenModel(createCtxModel(ctx, payload)));
|
||||||
|
request.templateParams(templateParams.map());
|
||||||
|
request.templateName(requestPrototype.templateName());
|
||||||
|
request.templateType(requestPrototype.templateType());
|
||||||
|
} else {
|
||||||
|
throw new TransformException("search requests needs either source or template name");
|
||||||
|
}
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.search;
|
||||||
|
|
||||||
|
import org.elasticsearch.action.search.SearchRequest;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.watcher.support.SearchRequestEquivalence;
|
||||||
|
import org.elasticsearch.watcher.support.SearchRequestParseException;
|
||||||
|
import org.elasticsearch.watcher.support.WatcherUtils;
|
||||||
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SearchTransform implements Transform {
|
||||||
|
|
||||||
|
public static final String TYPE = "search";
|
||||||
|
|
||||||
|
protected final SearchRequest request;
|
||||||
|
|
||||||
|
public SearchTransform(SearchRequest request) {
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchRequest getRequest() {
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
SearchTransform transform = (SearchTransform) o;
|
||||||
|
|
||||||
|
return SearchRequestEquivalence.INSTANCE.equivalent(request, transform.request);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return request.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
return WatcherUtils.writeSearchRequest(request, builder, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SearchTransform parse(String watchId, XContentParser parser) throws IOException {
|
||||||
|
try {
|
||||||
|
SearchRequest request = WatcherUtils.readSearchRequest(parser, ExecutableSearchTransform.DEFAULT_SEARCH_TYPE);
|
||||||
|
return new SearchTransform(request);
|
||||||
|
} catch (SearchRequestParseException srpe) {
|
||||||
|
throw new SearchTransformException("could not parse [{}] transform for watch [{}]. failed parsing search request", srpe, TYPE, watchId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Builder builder(SearchRequest request) {
|
||||||
|
return new Builder(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Result extends Transform.Result {
|
||||||
|
|
||||||
|
public Result(Payload payload) {
|
||||||
|
super(TYPE, payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected XContentBuilder xContentBody(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result parse(String watchId, XContentParser parser) throws IOException {
|
||||||
|
XContentParser.Token token = parser.currentToken();
|
||||||
|
if (token != XContentParser.Token.START_OBJECT) {
|
||||||
|
throw new SearchTransformException("could not parse [{}] transform result for watch [{}]. expected an object, but found [{}] instead", TYPE, watchId, token);
|
||||||
|
}
|
||||||
|
token = parser.nextToken();
|
||||||
|
if (token != XContentParser.Token.FIELD_NAME || !Field.PAYLOAD.match(parser.currentName())) {
|
||||||
|
throw new SearchTransformException("could not parse [{}] transform result for watch [{}]. expected a [{}] field, but found [{}] instead", TYPE, watchId, Field.PAYLOAD.getPreferredName(), token);
|
||||||
|
}
|
||||||
|
token = parser.nextToken();
|
||||||
|
if (token != XContentParser.Token.START_OBJECT) {
|
||||||
|
throw new SearchTransformException("could not parse [{}] transform result for watch [{}]. expected a [{}] field, but found [{}] instead", TYPE, watchId, Field.PAYLOAD.getPreferredName(), token);
|
||||||
|
}
|
||||||
|
return new SearchTransform.Result(new Payload.XContent(parser));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder implements Transform.Builder<SearchTransform> {
|
||||||
|
|
||||||
|
private final SearchRequest request;
|
||||||
|
|
||||||
|
public Builder(SearchRequest request) {
|
||||||
|
this.request = request;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SearchTransform build() {
|
||||||
|
return new SearchTransform(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.search;
|
||||||
|
|
||||||
|
import org.elasticsearch.watcher.transform.TransformException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SearchTransformException extends TransformException {
|
||||||
|
|
||||||
|
public SearchTransformException(String msg, Object... args) {
|
||||||
|
super(msg, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SearchTransformException(String msg, Throwable cause, Object... args) {
|
||||||
|
super(msg, cause, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.watcher.transform.search;
|
||||||
|
|
||||||
|
import org.elasticsearch.common.inject.Inject;
|
||||||
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
import org.elasticsearch.common.settings.Settings;
|
||||||
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
|
import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class SearchTransformFactory extends TransformFactory<SearchTransform, SearchTransform.Result, ExecutableSearchTransform> {
|
||||||
|
|
||||||
|
protected final ScriptServiceProxy scriptService;
|
||||||
|
protected final ClientProxy client;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SearchTransformFactory(Settings settings, ScriptServiceProxy scriptService, ClientProxy client) {
|
||||||
|
super(Loggers.getLogger(ExecutableSearchTransform.class, settings));
|
||||||
|
this.scriptService = scriptService;
|
||||||
|
this.client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return SearchTransform.TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SearchTransform parseTransform(String watchId, XContentParser parser) throws IOException {
|
||||||
|
return SearchTransform.parse(watchId, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SearchTransform.Result parseResult(String watchId, XContentParser parser) throws IOException {
|
||||||
|
return SearchTransform.Result.parse(watchId, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecutableSearchTransform createExecutable(SearchTransform transform) {
|
||||||
|
return new ExecutableSearchTransform(transform, transformLogger, scriptService, client);
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,7 +35,7 @@ import org.elasticsearch.watcher.license.LicenseService;
|
||||||
import org.elasticsearch.watcher.support.clock.Clock;
|
import org.elasticsearch.watcher.support.clock.Clock;
|
||||||
import org.elasticsearch.watcher.throttle.Throttler;
|
import org.elasticsearch.watcher.throttle.Throttler;
|
||||||
import org.elasticsearch.watcher.throttle.WatchThrottler;
|
import org.elasticsearch.watcher.throttle.WatchThrottler;
|
||||||
import org.elasticsearch.watcher.transform.Transform;
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
import org.elasticsearch.watcher.transform.TransformRegistry;
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
import org.elasticsearch.watcher.trigger.Trigger;
|
import org.elasticsearch.watcher.trigger.Trigger;
|
||||||
import org.elasticsearch.watcher.trigger.TriggerEngine;
|
import org.elasticsearch.watcher.trigger.TriggerEngine;
|
||||||
|
@ -67,11 +67,11 @@ public class Watch implements TriggerEngine.Job, ToXContent {
|
||||||
private final Map<String, Object> metadata;
|
private final Map<String, Object> metadata;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private final Transform transform;
|
private final ExecutableTransform transform;
|
||||||
|
|
||||||
private final transient AtomicLong nonceCounter = new AtomicLong();
|
private final transient AtomicLong nonceCounter = new AtomicLong();
|
||||||
|
|
||||||
public Watch(String name, Clock clock, LicenseService licenseService, Trigger trigger, ExecutableInput input, ExecutableCondition condition, @Nullable Transform transform,
|
public Watch(String name, Clock clock, LicenseService licenseService, Trigger trigger, ExecutableInput input, ExecutableCondition condition, @Nullable ExecutableTransform transform,
|
||||||
ExecutableActions actions, @Nullable Map<String, Object> metadata, @Nullable TimeValue throttlePeriod, @Nullable Status status) {
|
ExecutableActions actions, @Nullable Map<String, Object> metadata, @Nullable TimeValue throttlePeriod, @Nullable Status status) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.trigger = trigger;
|
this.trigger = trigger;
|
||||||
|
@ -99,7 +99,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
|
||||||
return condition;
|
return condition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Transform transform() {
|
public ExecutableTransform transform() {
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +234,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
|
||||||
ExecutableInput input = defaultInput;
|
ExecutableInput input = defaultInput;
|
||||||
ExecutableCondition condition = defaultCondition;
|
ExecutableCondition condition = defaultCondition;
|
||||||
ExecutableActions actions = null;
|
ExecutableActions actions = null;
|
||||||
Transform transform = null;
|
ExecutableTransform transform = null;
|
||||||
Map<String, Object> metatdata = null;
|
Map<String, Object> metatdata = null;
|
||||||
Status status = null;
|
Status status = null;
|
||||||
TimeValue throttlePeriod = defaultThrottleTimePeriod;
|
TimeValue throttlePeriod = defaultThrottleTimePeriod;
|
||||||
|
@ -256,7 +256,7 @@ public class Watch implements TriggerEngine.Job, ToXContent {
|
||||||
} else if (ACTIONS_FIELD.match(currentFieldName)) {
|
} else if (ACTIONS_FIELD.match(currentFieldName)) {
|
||||||
actions = actionRegistry.parseActions(id, parser);
|
actions = actionRegistry.parseActions(id, parser);
|
||||||
} else if (TRANSFORM_FIELD.match(currentFieldName)) {
|
} else if (TRANSFORM_FIELD.match(currentFieldName)) {
|
||||||
transform = transformRegistry.parse(parser);
|
transform = transformRegistry.parse(id, parser);
|
||||||
} else if (META_FIELD.match(currentFieldName)) {
|
} else if (META_FIELD.match(currentFieldName)) {
|
||||||
metatdata = parser.map();
|
metatdata = parser.map();
|
||||||
} else if (STATUS_FIELD.match(currentFieldName) && includeStatus) {
|
} else if (STATUS_FIELD.match(currentFieldName) && includeStatus) {
|
||||||
|
|
|
@ -85,7 +85,7 @@ public class WatchExecution implements ToXContent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (transformResult != null) {
|
if (transformResult != null) {
|
||||||
builder.startObject(Transform.Parser.TRANSFORM_RESULT_FIELD.getPreferredName()).field(transformResult.type(), transformResult).endObject();
|
builder.startObject(Transform.Field.TRANSFORM_RESULT.getPreferredName()).field(transformResult.type(), transformResult).endObject();
|
||||||
}
|
}
|
||||||
builder.startObject(Parser.ACTIONS_RESULTS.getPreferredName());
|
builder.startObject(Parser.ACTIONS_RESULTS.getPreferredName());
|
||||||
for (ActionWrapper.Result actionResult : actionsResults) {
|
for (ActionWrapper.Result actionResult : actionsResults) {
|
||||||
|
@ -131,8 +131,8 @@ public class WatchExecution implements ToXContent {
|
||||||
inputResult = inputRegistry.parseResult(wid.watchId(), parser);
|
inputResult = inputRegistry.parseResult(wid.watchId(), parser);
|
||||||
} else if (CONDITION_RESULT_FIELD.match(currentFieldName)) {
|
} else if (CONDITION_RESULT_FIELD.match(currentFieldName)) {
|
||||||
conditionResult = conditionRegistry.parseResult(wid.watchId(), parser);
|
conditionResult = conditionRegistry.parseResult(wid.watchId(), parser);
|
||||||
} else if (Transform.Parser.TRANSFORM_RESULT_FIELD.match(currentFieldName)) {
|
} else if (Transform.Field.TRANSFORM_RESULT.match(currentFieldName)) {
|
||||||
transformResult = transformRegistry.parseResult(parser);
|
transformResult = transformRegistry.parseResult(wid.watchId(), parser);
|
||||||
} else if (ACTIONS_RESULTS.match(currentFieldName)) {
|
} else if (ACTIONS_RESULTS.match(currentFieldName)) {
|
||||||
actionResults = actionRegistry.parseResults(wid, parser);
|
actionResults = actionRegistry.parseResults(wid, parser);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -6,9 +6,14 @@
|
||||||
package org.elasticsearch.watcher.actions;
|
package org.elasticsearch.watcher.actions;
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.ImmutableMap;
|
import org.elasticsearch.common.collect.ImmutableMap;
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
import org.elasticsearch.watcher.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformFactory;
|
||||||
import org.elasticsearch.watcher.transform.TransformRegistry;
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
|
@ -24,16 +29,27 @@ import static org.hamcrest.core.Is.is;
|
||||||
*/
|
*/
|
||||||
public class TransformMocks {
|
public class TransformMocks {
|
||||||
|
|
||||||
public static class TransformMock extends Transform<TransformMock.Result> {
|
public static class ExecutableTransformMock extends ExecutableTransform {
|
||||||
|
|
||||||
@Override
|
private static final String TYPE = "mock";
|
||||||
public String type() {
|
|
||||||
return "_transform";
|
public ExecutableTransformMock() {
|
||||||
|
super(new Transform() {
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
return builder.startObject().endObject();
|
||||||
|
}
|
||||||
|
}, Loggers.getLogger(ExecutableTransformMock.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result apply(WatchExecutionContext ctx, Payload payload) throws IOException {
|
public Transform.Result execute(WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
return new Result("_transform", new Payload.Simple("_key", "_value"));
|
return new Result(TYPE, new Payload.Simple("_key", "_value"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,41 +72,51 @@ public class TransformMocks {
|
||||||
|
|
||||||
public static class TransformRegistryMock extends TransformRegistry {
|
public static class TransformRegistryMock extends TransformRegistry {
|
||||||
|
|
||||||
public TransformRegistryMock(final Transform transform) {
|
public TransformRegistryMock(final ExecutableTransform executable) {
|
||||||
super(ImmutableMap.<String, Transform.Parser>of("_transform", new Transform.Parser() {
|
super(ImmutableMap.<String, TransformFactory>of("_transform", new TransformFactory(Loggers.getLogger(TransformRegistryMock.class)) {
|
||||||
@Override
|
@Override
|
||||||
public String type() {
|
public String type() {
|
||||||
return transform.type();
|
return executable.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Transform parse(XContentParser parser) throws IOException {
|
public Transform parseTransform(String watchId, XContentParser parser) throws IOException {
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
assertThat(parser.currentToken(), is(XContentParser.Token.END_OBJECT));
|
assertThat(parser.currentToken(), is(XContentParser.Token.END_OBJECT));
|
||||||
return transform;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Transform.Result parseResult(XContentParser parser) throws IOException {
|
public Transform.Result parseResult(String watchId, XContentParser parser) throws IOException {
|
||||||
return null; // should not be called when this ctor is used
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecutableTransform createExecutable(Transform transform) {
|
||||||
|
return executable;
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransformRegistryMock(final Transform.Result result) {
|
public TransformRegistryMock(final Transform.Result result) {
|
||||||
super(ImmutableMap.<String, Transform.Parser>of("_transform_type", new Transform.Parser() {
|
super(ImmutableMap.<String, TransformFactory>of("_transform_type", new TransformFactory(Loggers.getLogger(TransformRegistryMock.class)) {
|
||||||
@Override
|
@Override
|
||||||
public String type() {
|
public String type() {
|
||||||
return result.type();
|
return result.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Transform parse(XContentParser parser) throws IOException {
|
public Transform parseTransform(String watchId, XContentParser parser) throws IOException {
|
||||||
return null; // should not be called when this ctor is used.
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Transform.Result parseResult(XContentParser parser) throws IOException {
|
public ExecutableTransform createExecutable(Transform transform) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Transform.Result parseResult(String watchId, XContentParser parser) throws IOException {
|
||||||
assertThat(parser.currentToken(), is(XContentParser.Token.START_OBJECT));
|
assertThat(parser.currentToken(), is(XContentParser.Token.START_OBJECT));
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
assertThat(parser.currentToken(), is(XContentParser.Token.FIELD_NAME));
|
assertThat(parser.currentToken(), is(XContentParser.Token.FIELD_NAME));
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.elasticsearch.watcher.input.Input;
|
||||||
import org.elasticsearch.watcher.support.clock.Clock;
|
import org.elasticsearch.watcher.support.clock.Clock;
|
||||||
import org.elasticsearch.watcher.support.clock.ClockMock;
|
import org.elasticsearch.watcher.support.clock.ClockMock;
|
||||||
import org.elasticsearch.watcher.throttle.Throttler;
|
import org.elasticsearch.watcher.throttle.Throttler;
|
||||||
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
import org.elasticsearch.watcher.transform.Transform;
|
import org.elasticsearch.watcher.transform.Transform;
|
||||||
import org.elasticsearch.watcher.trigger.schedule.ScheduleTriggerEvent;
|
import org.elasticsearch.watcher.trigger.schedule.ScheduleTriggerEvent;
|
||||||
import org.elasticsearch.watcher.watch.*;
|
import org.elasticsearch.watcher.watch.*;
|
||||||
|
@ -77,8 +78,8 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
|
||||||
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
|
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
|
||||||
Throttler throttler = mock(Throttler.class);
|
Throttler throttler = mock(Throttler.class);
|
||||||
when(throttler.throttle(any(WatchExecutionContext.class))).thenReturn(throttleResult);
|
when(throttler.throttle(any(WatchExecutionContext.class))).thenReturn(throttleResult);
|
||||||
Transform transform = mock(Transform.class);
|
ExecutableTransform transform = mock(ExecutableTransform.class);
|
||||||
when(transform.apply(any(WatchExecutionContext.class), same(payload))).thenReturn(transformResult);
|
when(transform.execute(any(WatchExecutionContext.class), same(payload))).thenReturn(transformResult);
|
||||||
ActionWrapper action = mock(ActionWrapper.class);
|
ActionWrapper action = mock(ActionWrapper.class);
|
||||||
when(action.execute(any(WatchExecutionContext.class))).thenReturn(watchActionResult);
|
when(action.execute(any(WatchExecutionContext.class))).thenReturn(watchActionResult);
|
||||||
ExecutableActions actions = new ExecutableActions(Arrays.asList(action));
|
ExecutableActions actions = new ExecutableActions(Arrays.asList(action));
|
||||||
|
@ -104,7 +105,7 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
verify(condition, times(1)).execute(any(WatchExecutionContext.class));
|
verify(condition, times(1)).execute(any(WatchExecutionContext.class));
|
||||||
verify(throttler, times(1)).throttle(any(WatchExecutionContext.class));
|
verify(throttler, times(1)).throttle(any(WatchExecutionContext.class));
|
||||||
verify(transform, times(1)).apply(any(WatchExecutionContext.class), same(payload));
|
verify(transform, times(1)).execute(any(WatchExecutionContext.class), same(payload));
|
||||||
verify(action, times(1)).execute(any(WatchExecutionContext.class));
|
verify(action, times(1)).execute(any(WatchExecutionContext.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,8 +124,8 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
|
||||||
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
|
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
|
||||||
Throttler throttler = mock(Throttler.class);
|
Throttler throttler = mock(Throttler.class);
|
||||||
when(throttler.throttle(any(WatchExecutionContext.class))).thenReturn(throttleResult);
|
when(throttler.throttle(any(WatchExecutionContext.class))).thenReturn(throttleResult);
|
||||||
Transform transform = mock(Transform.class);
|
ExecutableTransform transform = mock(ExecutableTransform.class);
|
||||||
when(transform.apply(any(WatchExecutionContext.class), same(payload))).thenReturn(transformResult);
|
when(transform.execute(any(WatchExecutionContext.class), same(payload))).thenReturn(transformResult);
|
||||||
ActionWrapper action = mock(ActionWrapper.class);
|
ActionWrapper action = mock(ActionWrapper.class);
|
||||||
when(action.execute(any(WatchExecutionContext.class))).thenReturn(actionResult);
|
when(action.execute(any(WatchExecutionContext.class))).thenReturn(actionResult);
|
||||||
ExecutableActions actions = new ExecutableActions(Arrays.asList(action));
|
ExecutableActions actions = new ExecutableActions(Arrays.asList(action));
|
||||||
|
@ -151,7 +152,7 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
verify(condition, times(1)).execute(any(WatchExecutionContext.class));
|
verify(condition, times(1)).execute(any(WatchExecutionContext.class));
|
||||||
verify(throttler, times(1)).throttle(any(WatchExecutionContext.class));
|
verify(throttler, times(1)).throttle(any(WatchExecutionContext.class));
|
||||||
verify(transform, never()).apply(any(WatchExecutionContext.class), same(payload));
|
verify(transform, never()).execute(any(WatchExecutionContext.class), same(payload));
|
||||||
verify(action, never()).execute(any(WatchExecutionContext.class));
|
verify(action, never()).execute(any(WatchExecutionContext.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,8 +170,8 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
|
||||||
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
|
when(condition.execute(any(WatchExecutionContext.class))).thenReturn(conditionResult);
|
||||||
Throttler throttler = mock(Throttler.class);
|
Throttler throttler = mock(Throttler.class);
|
||||||
when(throttler.throttle(any(WatchExecutionContext.class))).thenReturn(throttleResult);
|
when(throttler.throttle(any(WatchExecutionContext.class))).thenReturn(throttleResult);
|
||||||
Transform transform = mock(Transform.class);
|
ExecutableTransform transform = mock(ExecutableTransform.class);
|
||||||
when(transform.apply(any(WatchExecutionContext.class), same(payload))).thenReturn(transformResult);
|
when(transform.execute(any(WatchExecutionContext.class), same(payload))).thenReturn(transformResult);
|
||||||
ActionWrapper action = mock(ActionWrapper.class);
|
ActionWrapper action = mock(ActionWrapper.class);
|
||||||
when(action.execute(any(WatchExecutionContext.class))).thenReturn(actionResult);
|
when(action.execute(any(WatchExecutionContext.class))).thenReturn(actionResult);
|
||||||
ExecutableActions actions = new ExecutableActions(Arrays.asList(action));
|
ExecutableActions actions = new ExecutableActions(Arrays.asList(action));
|
||||||
|
@ -197,7 +198,7 @@ public class ExecutionServiceTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
verify(condition, times(1)).execute(any(WatchExecutionContext.class));
|
verify(condition, times(1)).execute(any(WatchExecutionContext.class));
|
||||||
verify(throttler, never()).throttle(any(WatchExecutionContext.class));
|
verify(throttler, never()).throttle(any(WatchExecutionContext.class));
|
||||||
verify(transform, never()).apply(any(WatchExecutionContext.class), same(payload));
|
verify(transform, never()).execute(any(WatchExecutionContext.class), same(payload));
|
||||||
verify(action, never()).execute(any(WatchExecutionContext.class));
|
verify(action, never()).execute(any(WatchExecutionContext.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,8 @@ import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||||
import org.elasticsearch.watcher.support.template.xmustache.XMustacheTemplateEngine;
|
import org.elasticsearch.watcher.support.template.xmustache.XMustacheTemplateEngine;
|
||||||
import org.elasticsearch.watcher.support.template.Template;
|
import org.elasticsearch.watcher.support.template.Template;
|
||||||
import org.elasticsearch.watcher.support.template.TemplateEngine;
|
import org.elasticsearch.watcher.support.template.TemplateEngine;
|
||||||
import org.elasticsearch.watcher.transform.SearchTransform;
|
import org.elasticsearch.watcher.transform.search.ExecutableSearchTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.search.SearchTransform;
|
||||||
import org.elasticsearch.watcher.trigger.TriggerEvent;
|
import org.elasticsearch.watcher.trigger.TriggerEvent;
|
||||||
import org.elasticsearch.watcher.trigger.schedule.CronSchedule;
|
import org.elasticsearch.watcher.trigger.schedule.CronSchedule;
|
||||||
import org.elasticsearch.watcher.trigger.schedule.ScheduleTrigger;
|
import org.elasticsearch.watcher.trigger.schedule.ScheduleTrigger;
|
||||||
|
@ -131,7 +132,7 @@ public final class WatcherTestUtils {
|
||||||
|
|
||||||
SearchRequest conditionRequest = newInputSearchRequest("my-condition-index").source(searchSource().query(matchAllQuery()));
|
SearchRequest conditionRequest = newInputSearchRequest("my-condition-index").source(searchSource().query(matchAllQuery()));
|
||||||
SearchRequest transformRequest = newInputSearchRequest("my-payload-index").source(searchSource().query(matchAllQuery()));
|
SearchRequest transformRequest = newInputSearchRequest("my-payload-index").source(searchSource().query(matchAllQuery()));
|
||||||
transformRequest.searchType(SearchTransform.DEFAULT_SEARCH_TYPE);
|
transformRequest.searchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE);
|
||||||
conditionRequest.searchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE);
|
conditionRequest.searchType(ExecutableSearchInput.DEFAULT_SEARCH_TYPE);
|
||||||
|
|
||||||
List<ActionWrapper> actions = new ArrayList<>();
|
List<ActionWrapper> actions = new ArrayList<>();
|
||||||
|
@ -181,7 +182,7 @@ public final class WatcherTestUtils {
|
||||||
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? *")),
|
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? *")),
|
||||||
new ExecutableSimpleInput(new SimpleInput(new Payload.Simple(inputData)), logger),
|
new ExecutableSimpleInput(new SimpleInput(new Payload.Simple(inputData)), logger),
|
||||||
new ExecutableScriptCondition(new ScriptCondition(new Script("return true")), logger, scriptService),
|
new ExecutableScriptCondition(new ScriptCondition(new Script("return true")), logger, scriptService),
|
||||||
new SearchTransform(logger, scriptService, client, transformRequest),
|
new ExecutableSearchTransform(new SearchTransform(transformRequest), logger, scriptService, client),
|
||||||
new ExecutableActions(actions),
|
new ExecutableActions(actions),
|
||||||
metadata,
|
metadata,
|
||||||
new TimeValue(0),
|
new TimeValue(0),
|
||||||
|
|
|
@ -28,7 +28,8 @@ import org.elasticsearch.watcher.support.clock.SystemClock;
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests;
|
import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests;
|
||||||
import org.elasticsearch.watcher.test.WatcherTestUtils;
|
import org.elasticsearch.watcher.test.WatcherTestUtils;
|
||||||
import org.elasticsearch.watcher.transform.SearchTransform;
|
import org.elasticsearch.watcher.transform.search.ExecutableSearchTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.search.SearchTransform;
|
||||||
import org.elasticsearch.watcher.transport.actions.put.PutWatchResponse;
|
import org.elasticsearch.watcher.transport.actions.put.PutWatchResponse;
|
||||||
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsResponse;
|
import org.elasticsearch.watcher.transport.actions.stats.WatcherStatsResponse;
|
||||||
import org.elasticsearch.watcher.trigger.schedule.CronSchedule;
|
import org.elasticsearch.watcher.trigger.schedule.CronSchedule;
|
||||||
|
@ -91,7 +92,7 @@ public class BootStrapTests extends AbstractWatcherIntegrationTests {
|
||||||
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? 2035")), //Set this into the future so we don't get any extra runs
|
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? 2035")), //Set this into the future so we don't get any extra runs
|
||||||
new ExecutableSearchInput(new SearchInput(searchRequest, null), logger, scriptService(), ClientProxy.of(client())),
|
new ExecutableSearchInput(new SearchInput(searchRequest, null), logger, scriptService(), ClientProxy.of(client())),
|
||||||
new ExecutableScriptCondition(new ScriptCondition(new Script("return true")), logger, scriptService()),
|
new ExecutableScriptCondition(new ScriptCondition(new Script("return true")), logger, scriptService()),
|
||||||
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), searchRequest),
|
new ExecutableSearchTransform(new SearchTransform(searchRequest), logger, scriptService(), ClientProxy.of(client())),
|
||||||
new ExecutableActions(new ArrayList<ActionWrapper>()),
|
new ExecutableActions(new ArrayList<ActionWrapper>()),
|
||||||
null, // metadata
|
null, // metadata
|
||||||
new TimeValue(0),
|
new TimeValue(0),
|
||||||
|
@ -153,7 +154,7 @@ public class BootStrapTests extends AbstractWatcherIntegrationTests {
|
||||||
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? 2035")), //Set a cron schedule far into the future so this watch is never scheduled
|
new ScheduleTrigger(new CronSchedule("0/5 * * * * ? 2035")), //Set a cron schedule far into the future so this watch is never scheduled
|
||||||
new ExecutableSearchInput(new SearchInput(searchRequest, null), logger, scriptService(), ClientProxy.of(client())),
|
new ExecutableSearchInput(new SearchInput(searchRequest, null), logger, scriptService(), ClientProxy.of(client())),
|
||||||
new ExecutableScriptCondition(new ScriptCondition(new Script("return true")), logger, scriptService()),
|
new ExecutableScriptCondition(new ScriptCondition(new Script("return true")), logger, scriptService()),
|
||||||
new SearchTransform(logger, scriptService(), ClientProxy.of(client()), searchRequest),
|
new ExecutableSearchTransform(new SearchTransform(searchRequest), logger, scriptService(), ClientProxy.of(client())),
|
||||||
new ExecutableActions(new ArrayList<ActionWrapper>()),
|
new ExecutableActions(new ArrayList<ActionWrapper>()),
|
||||||
null, // metadata
|
null, // metadata
|
||||||
new TimeValue(0),
|
new TimeValue(0),
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.elasticsearch.action.search.SearchRequest;
|
||||||
import org.elasticsearch.action.search.SearchResponse;
|
import org.elasticsearch.action.search.SearchResponse;
|
||||||
import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests;
|
import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests;
|
||||||
import org.elasticsearch.watcher.test.WatcherTestUtils;
|
import org.elasticsearch.watcher.test.WatcherTestUtils;
|
||||||
import org.elasticsearch.watcher.transform.SearchTransform;
|
import org.elasticsearch.watcher.transform.search.ExecutableSearchTransform;
|
||||||
import org.elasticsearch.watcher.transport.actions.put.PutWatchResponse;
|
import org.elasticsearch.watcher.transport.actions.put.PutWatchResponse;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.search.SearchHit;
|
import org.elasticsearch.search.SearchHit;
|
||||||
|
@ -43,7 +43,7 @@ public class TransformSearchTests extends AbstractWatcherIntegrationTests {
|
||||||
|
|
||||||
SearchRequest inputRequest = WatcherTestUtils.newInputSearchRequest("my-condition-index").source(searchSource().query(matchAllQuery()));
|
SearchRequest inputRequest = WatcherTestUtils.newInputSearchRequest("my-condition-index").source(searchSource().query(matchAllQuery()));
|
||||||
SearchRequest transformRequest = WatcherTestUtils.newInputSearchRequest("my-payload-index").source(searchSource().query(matchAllQuery()));
|
SearchRequest transformRequest = WatcherTestUtils.newInputSearchRequest("my-payload-index").source(searchSource().query(matchAllQuery()));
|
||||||
transformRequest.searchType(SearchTransform.DEFAULT_SEARCH_TYPE);
|
transformRequest.searchType(ExecutableSearchTransform.DEFAULT_SEARCH_TYPE);
|
||||||
|
|
||||||
Map<String, Object> metadata = new HashMap<>();
|
Map<String, Object> metadata = new HashMap<>();
|
||||||
metadata.put("foo", "bar");
|
metadata.put("foo", "bar");
|
||||||
|
|
|
@ -7,12 +7,17 @@ package org.elasticsearch.watcher.transform;
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.ImmutableList;
|
import org.elasticsearch.common.collect.ImmutableList;
|
||||||
import org.elasticsearch.common.collect.ImmutableMap;
|
import org.elasticsearch.common.collect.ImmutableMap;
|
||||||
|
import org.elasticsearch.common.logging.ESLogger;
|
||||||
|
import org.elasticsearch.common.logging.Loggers;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
|
import org.elasticsearch.watcher.transform.chain.ChainTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.chain.ChainTransformFactory;
|
||||||
|
import org.elasticsearch.watcher.transform.chain.ExecutableChainTransform;
|
||||||
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -33,14 +38,19 @@ public class ChainTransformTests extends ElasticsearchTestCase {
|
||||||
@Test
|
@Test
|
||||||
public void testApply() throws Exception {
|
public void testApply() throws Exception {
|
||||||
ChainTransform transform = new ChainTransform(ImmutableList.<Transform>of(
|
ChainTransform transform = new ChainTransform(ImmutableList.<Transform>of(
|
||||||
new NamedTransform("name1"),
|
new NamedExecutableTransform.Transform("name1"),
|
||||||
new NamedTransform("name2"),
|
new NamedExecutableTransform.Transform("name2"),
|
||||||
new NamedTransform("name3")));
|
new NamedExecutableTransform.Transform("name3")
|
||||||
|
));
|
||||||
|
ExecutableChainTransform executable = new ExecutableChainTransform(transform, logger, ImmutableList.<ExecutableTransform>of(
|
||||||
|
new NamedExecutableTransform("name1"),
|
||||||
|
new NamedExecutableTransform("name2"),
|
||||||
|
new NamedExecutableTransform("name3")));
|
||||||
|
|
||||||
WatchExecutionContext ctx = mock(WatchExecutionContext.class);
|
WatchExecutionContext ctx = mock(WatchExecutionContext.class);
|
||||||
Payload payload = new Payload.Simple(new HashMap<String, Object>());
|
Payload payload = new Payload.Simple(new HashMap<String, Object>());
|
||||||
|
|
||||||
Transform.Result result = transform.apply(ctx, payload);
|
Transform.Result result = executable.execute(ctx, payload);
|
||||||
|
|
||||||
Map<String, Object> data = result.payload().data();
|
Map<String, Object> data = result.payload().data();
|
||||||
assertThat(data, notNullValue());
|
assertThat(data, notNullValue());
|
||||||
|
@ -53,12 +63,12 @@ public class ChainTransformTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testParser() throws Exception {
|
public void testParser() throws Exception {
|
||||||
Map<String, Transform.Parser> parsers = ImmutableMap.<String, Transform.Parser>builder()
|
Map<String, TransformFactory> factories = ImmutableMap.<String, TransformFactory>builder()
|
||||||
.put("named", new NamedTransform.Parser())
|
.put("named", new NamedExecutableTransform.Factory(logger))
|
||||||
.build();
|
.build();
|
||||||
TransformRegistry registry = new TransformRegistry(parsers);
|
TransformRegistry registry = new TransformRegistry(factories);
|
||||||
|
|
||||||
ChainTransform.Parser transformParser = new ChainTransform.Parser(registry);
|
ChainTransformFactory transformParser = new ChainTransformFactory(registry);
|
||||||
|
|
||||||
XContentBuilder builder = jsonBuilder().startArray()
|
XContentBuilder builder = jsonBuilder().startArray()
|
||||||
.startObject().startObject("named").field("name", "name1").endObject().endObject()
|
.startObject().startObject("named").field("name", "name1").endObject().endObject()
|
||||||
|
@ -68,45 +78,57 @@ public class ChainTransformTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
ChainTransform transform = transformParser.parse(parser);
|
ExecutableChainTransform executable = transformParser.parseExecutable("_id", parser);
|
||||||
assertThat(transform, notNullValue());
|
assertThat(executable, notNullValue());
|
||||||
assertThat(transform.transforms(), notNullValue());
|
assertThat(executable.transform.getTransforms(), notNullValue());
|
||||||
assertThat(transform.transforms(), hasSize(3));
|
assertThat(executable.transform.getTransforms(), hasSize(3));
|
||||||
for (int i = 0; i < transform.transforms().size(); i++) {
|
for (int i = 0; i < executable.transform.getTransforms().size(); i++) {
|
||||||
assertThat(transform.transforms().get(i), instanceOf(NamedTransform.class));
|
assertThat(executable.executableTransforms().get(i), instanceOf(NamedExecutableTransform.class));
|
||||||
assertThat(((NamedTransform) transform.transforms().get(i)).name, is("name" + (i + 1)));
|
assertThat(((NamedExecutableTransform) executable.executableTransforms().get(i)).transform().name, is("name" + (i + 1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class NamedTransform extends Transform<NamedTransform.Result> {
|
private static class NamedExecutableTransform extends ExecutableTransform<NamedExecutableTransform.Transform, NamedExecutableTransform.Result> {
|
||||||
|
|
||||||
private final String name;
|
private static final String TYPE = "named";
|
||||||
|
|
||||||
public NamedTransform(String name) {
|
public NamedExecutableTransform(String name) {
|
||||||
this.name = name;
|
this(new Transform(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public NamedExecutableTransform(Transform transform) {
|
||||||
|
super(transform, Loggers.getLogger(NamedExecutableTransform.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String type() {
|
public Result execute(WatchExecutionContext ctx, Payload payload) throws IOException {
|
||||||
return "noop";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Result apply(WatchExecutionContext ctx, Payload payload) throws IOException {
|
|
||||||
|
|
||||||
Map<String, Object> data = new HashMap<>(payload.data());
|
Map<String, Object> data = new HashMap<>(payload.data());
|
||||||
List<String> names = (List<String>) data.get("names");
|
List<String> names = (List<String>) data.get("names");
|
||||||
if (names == null) {
|
if (names == null) {
|
||||||
names = new ArrayList<>();
|
names = new ArrayList<>();
|
||||||
data.put("names", names);
|
data.put("names", names);
|
||||||
}
|
}
|
||||||
names.add(name);
|
names.add(transform.name);
|
||||||
return new Result("named", new Payload.Simple(data));
|
return new Result("named", new Payload.Simple(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public static class Transform implements org.elasticsearch.watcher.transform.Transform {
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
|
||||||
return builder.startObject().field("name", name).endObject();
|
private final String name;
|
||||||
|
|
||||||
|
public Transform(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
|
return builder.startObject().field("name", name).endObject();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Result extends Transform.Result {
|
public static class Result extends Transform.Result {
|
||||||
|
@ -121,15 +143,19 @@ public class ChainTransformTests extends ElasticsearchTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Parser implements Transform.Parser<Result, NamedTransform> {
|
public static class Factory extends TransformFactory<Transform, Result, NamedExecutableTransform> {
|
||||||
|
|
||||||
@Override
|
public Factory(ESLogger transformLogger) {
|
||||||
public String type() {
|
super(transformLogger);
|
||||||
return "named";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NamedTransform parse(XContentParser parser) throws IOException {
|
public String type() {
|
||||||
|
return TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Transform parseTransform(String watchId, XContentParser parser) throws IOException {
|
||||||
assert parser.currentToken() == XContentParser.Token.START_OBJECT;
|
assert parser.currentToken() == XContentParser.Token.START_OBJECT;
|
||||||
XContentParser.Token token = parser.nextToken();
|
XContentParser.Token token = parser.nextToken();
|
||||||
assert token == XContentParser.Token.FIELD_NAME; // the "name" field
|
assert token == XContentParser.Token.FIELD_NAME; // the "name" field
|
||||||
|
@ -138,11 +164,11 @@ public class ChainTransformTests extends ElasticsearchTestCase {
|
||||||
String name = parser.text();
|
String name = parser.text();
|
||||||
token = parser.nextToken();
|
token = parser.nextToken();
|
||||||
assert token == XContentParser.Token.END_OBJECT;
|
assert token == XContentParser.Token.END_OBJECT;
|
||||||
return new NamedTransform(name);
|
return new Transform(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result parseResult(XContentParser parser) throws IOException {
|
public Result parseResult(String watchId, XContentParser parser) throws IOException {
|
||||||
assert parser.currentToken() == XContentParser.Token.START_OBJECT;
|
assert parser.currentToken() == XContentParser.Token.START_OBJECT;
|
||||||
XContentParser.Token token = parser.nextToken();
|
XContentParser.Token token = parser.nextToken();
|
||||||
assert token == XContentParser.Token.FIELD_NAME; // the "payload" field
|
assert token == XContentParser.Token.FIELD_NAME; // the "payload" field
|
||||||
|
@ -153,6 +179,11 @@ public class ChainTransformTests extends ElasticsearchTestCase {
|
||||||
assert token == XContentParser.Token.END_OBJECT;
|
assert token == XContentParser.Token.END_OBJECT;
|
||||||
return new Result("named", payload);
|
return new Result("named", payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamedExecutableTransform createExecutable(Transform transform) {
|
||||||
|
return new NamedExecutableTransform(transform);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,11 @@ package org.elasticsearch.watcher.transform;
|
||||||
|
|
||||||
import com.carrotsearch.ant.tasks.junit4.dependencies.com.google.common.collect.ImmutableList;
|
import com.carrotsearch.ant.tasks.junit4.dependencies.com.google.common.collect.ImmutableList;
|
||||||
import com.carrotsearch.ant.tasks.junit4.dependencies.com.google.common.collect.ImmutableSet;
|
import com.carrotsearch.ant.tasks.junit4.dependencies.com.google.common.collect.ImmutableSet;
|
||||||
|
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
|
import org.elasticsearch.watcher.transform.script.ExecutableScriptTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.script.ScriptTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.script.ScriptTransformFactory;
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.watcher.support.Script;
|
import org.elasticsearch.watcher.support.Script;
|
||||||
import org.elasticsearch.watcher.support.Variables;
|
import org.elasticsearch.watcher.support.Variables;
|
||||||
|
@ -41,7 +45,7 @@ public class ScriptTransformTests extends ElasticsearchTestCase {
|
||||||
ScriptService.ScriptType type = randomFrom(ScriptService.ScriptType.values());
|
ScriptService.ScriptType type = randomFrom(ScriptService.ScriptType.values());
|
||||||
Map<String, Object> params = Collections.emptyMap();
|
Map<String, Object> params = Collections.emptyMap();
|
||||||
Script script = new Script("_script", type, "_lang", params);
|
Script script = new Script("_script", type, "_lang", params);
|
||||||
ScriptTransform transform = new ScriptTransform(service, script);
|
ExecutableScriptTransform transform = new ExecutableScriptTransform(new ScriptTransform(script), logger, service);
|
||||||
|
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
||||||
|
|
||||||
|
@ -57,7 +61,7 @@ public class ScriptTransformTests extends ElasticsearchTestCase {
|
||||||
when(executable.run()).thenReturn(transformed);
|
when(executable.run()).thenReturn(transformed);
|
||||||
when(service.executable("_lang", "_script", type, model)).thenReturn(executable);
|
when(service.executable("_lang", "_script", type, model)).thenReturn(executable);
|
||||||
|
|
||||||
Transform.Result result = transform.apply(ctx, payload);
|
Transform.Result result = transform.execute(ctx, payload);
|
||||||
assertThat(result, notNullValue());
|
assertThat(result, notNullValue());
|
||||||
assertThat(result.type(), is(ScriptTransform.TYPE));
|
assertThat(result.type(), is(ScriptTransform.TYPE));
|
||||||
assertThat(result.payload().data(), equalTo(transformed));
|
assertThat(result.payload().data(), equalTo(transformed));
|
||||||
|
@ -69,7 +73,7 @@ public class ScriptTransformTests extends ElasticsearchTestCase {
|
||||||
ScriptService.ScriptType type = randomFrom(ScriptService.ScriptType.values());
|
ScriptService.ScriptType type = randomFrom(ScriptService.ScriptType.values());
|
||||||
Map<String, Object> params = Collections.emptyMap();
|
Map<String, Object> params = Collections.emptyMap();
|
||||||
Script script = new Script("_script", type, "_lang", params);
|
Script script = new Script("_script", type, "_lang", params);
|
||||||
ScriptTransform transform = new ScriptTransform(service, script);
|
ExecutableScriptTransform transform = new ExecutableScriptTransform(new ScriptTransform(script), logger, service);
|
||||||
|
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
||||||
|
|
||||||
|
@ -82,7 +86,7 @@ public class ScriptTransformTests extends ElasticsearchTestCase {
|
||||||
when(executable.run()).thenReturn(value);
|
when(executable.run()).thenReturn(value);
|
||||||
when(service.executable("_lang", "_script", type, model)).thenReturn(executable);
|
when(service.executable("_lang", "_script", type, model)).thenReturn(executable);
|
||||||
|
|
||||||
Transform.Result result = transform.apply(ctx, payload);
|
Transform.Result result = transform.execute(ctx, payload);
|
||||||
assertThat(result, notNullValue());
|
assertThat(result, notNullValue());
|
||||||
assertThat(result.type(), is(ScriptTransform.TYPE));
|
assertThat(result.type(), is(ScriptTransform.TYPE));
|
||||||
assertThat(result.payload().data().size(), is(1));
|
assertThat(result.payload().data().size(), is(1));
|
||||||
|
@ -102,8 +106,8 @@ public class ScriptTransformTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
ScriptTransform transform = new ScriptTransform.Parser(service).parse(parser);
|
ExecutableScriptTransform transform = new ScriptTransformFactory(ImmutableSettings.EMPTY, service).parseExecutable("_id", parser);
|
||||||
assertThat(transform.script(), equalTo(new Script("_script", type, "_lang", ImmutableMap.<String, Object>builder().put("key", "value").build())));
|
assertThat(transform.transform().getScript(), equalTo(new Script("_script", type, "_lang", ImmutableMap.<String, Object>builder().put("key", "value").build())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -113,7 +117,7 @@ public class ScriptTransformTests extends ElasticsearchTestCase {
|
||||||
|
|
||||||
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
ScriptTransform transform = new ScriptTransform.Parser(service).parse(parser);
|
ExecutableScriptTransform transform = new ScriptTransformFactory(ImmutableSettings.EMPTY, service).parseExecutable("_id", parser);
|
||||||
assertThat(transform.script(), equalTo(new Script("_script", ScriptService.ScriptType.INLINE, ScriptService.DEFAULT_LANG, ImmutableMap.<String, Object>of())));
|
assertThat(transform.transform().getScript(), equalTo(new Script("_script", ScriptService.ScriptType.INLINE, ScriptService.DEFAULT_LANG, ImmutableMap.<String, Object>of())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@ import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.script.ScriptService;
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
import org.elasticsearch.watcher.support.init.proxy.ClientProxy;
|
||||||
import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests;
|
import org.elasticsearch.watcher.test.AbstractWatcherIntegrationTests;
|
||||||
|
import org.elasticsearch.watcher.transform.search.ExecutableSearchTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.search.SearchTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.search.SearchTransformFactory;
|
||||||
import org.elasticsearch.watcher.trigger.schedule.ScheduleTriggerEvent;
|
import org.elasticsearch.watcher.trigger.schedule.ScheduleTriggerEvent;
|
||||||
import org.elasticsearch.watcher.watch.Payload;
|
import org.elasticsearch.watcher.watch.Payload;
|
||||||
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
import org.elasticsearch.watcher.execution.WatchExecutionContext;
|
||||||
|
@ -51,11 +54,11 @@ public class SearchTransformTests extends AbstractWatcherIntegrationTests {
|
||||||
.startObject("match_all").endObject()
|
.startObject("match_all").endObject()
|
||||||
.endObject()
|
.endObject()
|
||||||
.endObject());
|
.endObject());
|
||||||
SearchTransform transform = new SearchTransform(logger, scriptService(), ClientProxy.of(client()), request);
|
ExecutableSearchTransform transform = new ExecutableSearchTransform(new SearchTransform(request), logger, scriptService(), ClientProxy.of(client()));
|
||||||
|
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
WatchExecutionContext ctx = mockExecutionContext("_name", EMPTY_PAYLOAD);
|
||||||
|
|
||||||
Transform.Result result = transform.apply(ctx, EMPTY_PAYLOAD);
|
Transform.Result result = transform.execute(ctx, EMPTY_PAYLOAD);
|
||||||
assertThat(result, notNullValue());
|
assertThat(result, notNullValue());
|
||||||
assertThat(result.type(), is(SearchTransform.TYPE));
|
assertThat(result.type(), is(SearchTransform.TYPE));
|
||||||
|
|
||||||
|
@ -108,14 +111,14 @@ public class SearchTransformTests extends AbstractWatcherIntegrationTests {
|
||||||
.must(rangeFilter("date").lt("{{ctx.execution_time}}"))
|
.must(rangeFilter("date").lt("{{ctx.execution_time}}"))
|
||||||
.must(termFilter("value", "{{ctx.payload.value}}")))));
|
.must(termFilter("value", "{{ctx.payload.value}}")))));
|
||||||
|
|
||||||
SearchTransform transform = new SearchTransform(logger, scriptService(), ClientProxy.of(client()), request);
|
ExecutableSearchTransform transform = new ExecutableSearchTransform(new SearchTransform(request), logger, scriptService(), ClientProxy.of(client()));
|
||||||
|
|
||||||
ScheduleTriggerEvent event = new ScheduleTriggerEvent("_name", parseDate("2015-01-04T00:00:00"), parseDate("2015-01-01T00:00:00"));
|
ScheduleTriggerEvent event = new ScheduleTriggerEvent("_name", parseDate("2015-01-04T00:00:00"), parseDate("2015-01-01T00:00:00"));
|
||||||
WatchExecutionContext ctx = mockExecutionContext("_name", parseDate("2015-01-04T00:00:00"), event, EMPTY_PAYLOAD);
|
WatchExecutionContext ctx = mockExecutionContext("_name", parseDate("2015-01-04T00:00:00"), event, EMPTY_PAYLOAD);
|
||||||
|
|
||||||
Payload payload = simplePayload("value", "val_3");
|
Payload payload = simplePayload("value", "val_3");
|
||||||
|
|
||||||
Transform.Result result = transform.apply(ctx, payload);
|
Transform.Result result = transform.execute(ctx, payload);
|
||||||
assertThat(result, notNullValue());
|
assertThat(result, notNullValue());
|
||||||
assertThat(result.type(), is(SearchTransform.TYPE));
|
assertThat(result.type(), is(SearchTransform.TYPE));
|
||||||
|
|
||||||
|
@ -175,23 +178,23 @@ public class SearchTransformTests extends AbstractWatcherIntegrationTests {
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
XContentParser parser = JsonXContent.jsonXContent.createParser(builder.bytes());
|
||||||
parser.nextToken();
|
parser.nextToken();
|
||||||
SearchTransform transform = new SearchTransform.Parser(ImmutableSettings.EMPTY, scriptService(), ClientProxy.of(client())).parse(parser);
|
ExecutableSearchTransform executable = new SearchTransformFactory(ImmutableSettings.EMPTY, scriptService(), ClientProxy.of(client())).parseExecutable("_id", parser);
|
||||||
assertThat(transform, notNullValue());
|
assertThat(executable, notNullValue());
|
||||||
assertThat(transform.type(), is(SearchTransform.TYPE));
|
assertThat(executable.type(), is(SearchTransform.TYPE));
|
||||||
assertThat(transform.request, notNullValue());
|
assertThat(executable.transform().getRequest(), notNullValue());
|
||||||
if (indices != null) {
|
if (indices != null) {
|
||||||
assertThat(transform.request.indices(), arrayContainingInAnyOrder(indices));
|
assertThat(executable.transform().getRequest().indices(), arrayContainingInAnyOrder(indices));
|
||||||
}
|
}
|
||||||
if (searchType != null) {
|
if (searchType != null) {
|
||||||
assertThat(transform.request.searchType(), is(searchType));
|
assertThat(executable.transform().getRequest().searchType(), is(searchType));
|
||||||
}
|
}
|
||||||
if (templateName != null) {
|
if (templateName != null) {
|
||||||
assertThat(transform.request.templateName(), equalTo(templateName));
|
assertThat(executable.transform().getRequest().templateName(), equalTo(templateName));
|
||||||
}
|
}
|
||||||
if (templateType != null) {
|
if (templateType != null) {
|
||||||
assertThat(transform.request.templateType(), equalTo(templateType));
|
assertThat(executable.transform().getRequest().templateType(), equalTo(templateType));
|
||||||
}
|
}
|
||||||
assertThat(transform.request.source().toBytes(), equalTo(source.toBytes()));
|
assertThat(executable.transform().getRequest().source().toBytes(), equalTo(source.toBytes()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Map<String, Object> doc(String date, String value) {
|
private static Map<String, Object> doc(String date, String value) {
|
||||||
|
|
|
@ -68,7 +68,18 @@ import org.elasticsearch.watcher.support.init.proxy.ScriptServiceProxy;
|
||||||
import org.elasticsearch.watcher.support.template.Template;
|
import org.elasticsearch.watcher.support.template.Template;
|
||||||
import org.elasticsearch.watcher.support.template.TemplateEngine;
|
import org.elasticsearch.watcher.support.template.TemplateEngine;
|
||||||
import org.elasticsearch.watcher.test.WatcherTestUtils;
|
import org.elasticsearch.watcher.test.WatcherTestUtils;
|
||||||
import org.elasticsearch.watcher.transform.*;
|
import org.elasticsearch.watcher.transform.ExecutableTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformFactory;
|
||||||
|
import org.elasticsearch.watcher.transform.TransformRegistry;
|
||||||
|
import org.elasticsearch.watcher.transform.chain.ChainTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.chain.ChainTransformFactory;
|
||||||
|
import org.elasticsearch.watcher.transform.chain.ExecutableChainTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.script.ExecutableScriptTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.script.ScriptTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.script.ScriptTransformFactory;
|
||||||
|
import org.elasticsearch.watcher.transform.search.ExecutableSearchTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.search.SearchTransform;
|
||||||
|
import org.elasticsearch.watcher.transform.search.SearchTransformFactory;
|
||||||
import org.elasticsearch.watcher.trigger.Trigger;
|
import org.elasticsearch.watcher.trigger.Trigger;
|
||||||
import org.elasticsearch.watcher.trigger.TriggerEngine;
|
import org.elasticsearch.watcher.trigger.TriggerEngine;
|
||||||
import org.elasticsearch.watcher.trigger.TriggerService;
|
import org.elasticsearch.watcher.trigger.TriggerService;
|
||||||
|
@ -124,7 +135,7 @@ public class WatchTests extends ElasticsearchTestCase {
|
||||||
ExecutableCondition condition = randomCondition();
|
ExecutableCondition condition = randomCondition();
|
||||||
ConditionRegistry conditionRegistry = registry(condition);
|
ConditionRegistry conditionRegistry = registry(condition);
|
||||||
|
|
||||||
Transform transform = randomTransform();
|
ExecutableTransform transform = randomTransform();
|
||||||
|
|
||||||
ExecutableActions actions = randomActions();
|
ExecutableActions actions = randomActions();
|
||||||
ActionRegistry actionRegistry = registry(actions, transformRegistry);
|
ActionRegistry actionRegistry = registry(actions, transformRegistry);
|
||||||
|
@ -252,27 +263,30 @@ public class WatchTests extends ElasticsearchTestCase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Transform randomTransform() {
|
private ExecutableTransform randomTransform() {
|
||||||
String type = randomFrom(ScriptTransform.TYPE, SearchTransform.TYPE, ChainTransform.TYPE);
|
String type = randomFrom(ScriptTransform.TYPE, SearchTransform.TYPE, ChainTransform.TYPE);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ScriptTransform.TYPE:
|
case ScriptTransform.TYPE:
|
||||||
return new ScriptTransform(scriptService, new Script("_script"));
|
return new ExecutableScriptTransform(new ScriptTransform(new Script("_script")), logger, scriptService);
|
||||||
case SearchTransform.TYPE:
|
case SearchTransform.TYPE:
|
||||||
return new SearchTransform(logger, scriptService, client, matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS));
|
return new ExecutableSearchTransform(new SearchTransform(matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS)), logger, scriptService, client);
|
||||||
default: // chain
|
default: // chain
|
||||||
return new ChainTransform(ImmutableList.<Transform>of(
|
ChainTransform chainTransform = new ChainTransform(ImmutableList.of(
|
||||||
new SearchTransform(logger, scriptService, client, matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS)),
|
new SearchTransform(matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS)),
|
||||||
new ScriptTransform(scriptService, new Script("_script"))));
|
new ScriptTransform(new Script("_script"))));
|
||||||
|
return new ExecutableChainTransform(chainTransform, logger, ImmutableList.<ExecutableTransform>of(
|
||||||
|
new ExecutableSearchTransform(new SearchTransform(matchAllRequest(WatcherUtils.DEFAULT_INDICES_OPTIONS)), logger, scriptService, client),
|
||||||
|
new ExecutableScriptTransform(new ScriptTransform(new Script("_script")), logger, scriptService)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TransformRegistry transformRegistry() {
|
private TransformRegistry transformRegistry() {
|
||||||
ImmutableMap.Builder<String, Transform.Parser> parsers = ImmutableMap.builder();
|
ImmutableMap.Builder<String, TransformFactory> factories = ImmutableMap.builder();
|
||||||
ChainTransform.Parser parser = new ChainTransform.Parser();
|
ChainTransformFactory parser = new ChainTransformFactory();
|
||||||
parsers.put(ChainTransform.TYPE, parser);
|
factories.put(ChainTransform.TYPE, parser);
|
||||||
parsers.put(ScriptTransform.TYPE, new ScriptTransform.Parser(scriptService));
|
factories.put(ScriptTransform.TYPE, new ScriptTransformFactory(settings, scriptService));
|
||||||
parsers.put(SearchTransform.TYPE, new SearchTransform.Parser(settings, scriptService, client));
|
factories.put(SearchTransform.TYPE, new SearchTransformFactory(settings, scriptService, client));
|
||||||
TransformRegistry registry = new TransformRegistry(parsers.build());
|
TransformRegistry registry = new TransformRegistry(factories.build());
|
||||||
parser.init(registry);
|
parser.init(registry);
|
||||||
return registry;
|
return registry;
|
||||||
}
|
}
|
||||||
|
@ -280,7 +294,7 @@ public class WatchTests extends ElasticsearchTestCase {
|
||||||
private ExecutableActions randomActions() {
|
private ExecutableActions randomActions() {
|
||||||
ImmutableList.Builder<ActionWrapper> list = ImmutableList.builder();
|
ImmutableList.Builder<ActionWrapper> list = ImmutableList.builder();
|
||||||
if (randomBoolean()) {
|
if (randomBoolean()) {
|
||||||
Transform transform = randomTransform();
|
ExecutableTransform transform = randomTransform();
|
||||||
EmailAction action = new EmailAction(EmailTemplate.builder().build(), null, null, Profile.STANDARD, randomBoolean());
|
EmailAction action = new EmailAction(EmailTemplate.builder().build(), null, null, Profile.STANDARD, randomBoolean());
|
||||||
list.add(new ActionWrapper("_email_" + randomAsciiOfLength(8), transform, new ExecutableEmailAction(action, logger, emailService, templateEngine)));
|
list.add(new ActionWrapper("_email_" + randomAsciiOfLength(8), transform, new ExecutableEmailAction(action, logger, emailService, templateEngine)));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue