Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

inject the backend query type map for pluggable backend selection #21120

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.google.inject.multibindings.MapBinder;
import org.graylog.plugins.views.ViewsModule;
import org.graylog.plugins.views.search.SearchType;
import org.graylog.plugins.views.search.elasticsearch.ElasticsearchQueryString;
import org.graylog.plugins.views.search.engine.GeneratedQueryContext;
import org.graylog.plugins.views.search.engine.QueryBackend;
import org.graylog.plugins.views.search.export.ExportBackend;
Expand Down Expand Up @@ -86,8 +87,7 @@ public ViewsESBackendModule(SearchVersion supportedSearchVersion) {
protected void configure() {
install(new FactoryModuleBuilder().build(ESGeneratedQueryContext.Factory.class));

bindForVersion(supportedSearchVersion, new TypeLiteral<QueryBackend<? extends GeneratedQueryContext>>() {})
.to(ElasticsearchBackend.class);
registerVersionedQueryBackend(supportedSearchVersion, ElasticsearchQueryString.NAME, ElasticsearchBackend.class);

registerESSearchTypeHandler(MessageList.NAME, ESMessageList.class);
registerESSearchTypeHandler(EventList.NAME, ESEventList.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.google.inject.multibindings.OptionalBinder;
import org.graylog.plugins.views.ViewsModule;
import org.graylog.plugins.views.search.SearchType;
import org.graylog.plugins.views.search.elasticsearch.ElasticsearchQueryString;
import org.graylog.plugins.views.search.engine.GeneratedQueryContext;
import org.graylog.plugins.views.search.engine.QueryBackend;
import org.graylog.plugins.views.search.export.ExportBackend;
Expand Down Expand Up @@ -89,8 +90,7 @@ public ViewsOSBackendModule(SearchVersion supportedSearchVersion) {
protected void configure() {
install(new FactoryModuleBuilder().build(OSGeneratedQueryContext.Factory.class));

bindForVersion(supportedSearchVersion, new TypeLiteral<QueryBackend<? extends GeneratedQueryContext>>() {})
.to(OpenSearchBackend.class);
registerVersionedQueryBackend(supportedSearchVersion, ElasticsearchQueryString.NAME, OpenSearchBackend.class);

registerOSSearchTypeHandler(MessageList.NAME, OSMessageList.class);
registerOSSearchTypeHandler(EventList.NAME, OSEventListDelegate.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,22 @@ protected void registerPivotAggregationFunction(String name, String description,
seriesSpecBinder().addBinding(name).toInstance(SeriesDescription.create(name, description));
}

protected MapBinder<String, QueryBackend<? extends GeneratedQueryContext>> queryBackendBinder(SearchVersion version) {
protected MapBinder<String, QueryBackend<? extends GeneratedQueryContext>> queryBackendBinder() {
return MapBinder.newMapBinder(binder(),
TypeLiteral.get(String.class),
new TypeLiteral<QueryBackend<? extends GeneratedQueryContext>>() {});
new TypeLiteral<>() {});

}

protected ScopedBindingBuilder registerQueryBackend(SearchVersion version, String name, Class<? extends QueryBackend<? extends GeneratedQueryContext>> implementation) {
return queryBackendBinder(version).addBinding(name).to(implementation);
/**
* Use this binder for versioned backends, it also registers the backend in the overall MapBinder in
* @param version
* @param name
* @param implementation
*/
protected void registerVersionedQueryBackend(SearchVersion version, String name, Class<? extends QueryBackend<? extends GeneratedQueryContext>> implementation) {
bindForVersion(version, new TypeLiteral<QueryBackend<? extends GeneratedQueryContext>>() {}).to(implementation);
queryBackendBinder().addBinding(name).to(implementation);
}

protected void registerESQueryDecorator(Class<? extends QueryStringDecorator> esQueryDecorator) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ public class QueryEngine {

// TODO proper thread pool with tunable settings
private final Executor queryPool = Executors.newFixedThreadPool(4, new ThreadFactoryBuilder().setNameFormat("query-engine-%d").build());
private final QueryBackend<? extends GeneratedQueryContext> backend;
private final Map<String, QueryBackend<? extends GeneratedQueryContext>> backends;

@Inject
public QueryEngine(QueryBackend<? extends GeneratedQueryContext> backend,
public QueryEngine(Map<String, QueryBackend<? extends GeneratedQueryContext>> backends,
Set<QueryMetadataDecorator> queryMetadataDecorators,
QueryParser queryParser) {
this.backend = backend;
this.backends = backends;
this.queryMetadataDecorators = queryMetadataDecorators;
this.queryParser = queryParser;
}
Expand All @@ -75,6 +75,7 @@ public QueryMetadata parse(Search search, Query query) {
public ExplainResults explain(SearchJob searchJob, Set<SearchError> validationErrors, DateTimeZone timezone) {
final Map<String, ExplainResults.QueryExplainResult> queries = searchJob.getSearch().queries().stream()
.collect(Collectors.toMap(Query::id, q -> {
var backend = backends.get(q.query().type());
final GeneratedQueryContext generatedQueryContext = backend.generate(q, Set.of(), timezone);

return backend.explain(searchJob, q, generatedQueryContext);
Expand Down Expand Up @@ -116,6 +117,7 @@ public SearchJob execute(SearchJob searchJob, Set<SearchError> validationErrors,
}

private QueryResult prepareAndRun(SearchJob searchJob, Query query, Set<SearchError> validationErrors, DateTimeZone timezone) {
final var backend = backends.get(query.query().type());
LOG.debug("[{}] Using {} to generate query", query.id(), backend);
// with all the results done, we can execute the current query and eventually complete our own result
// if any of this throws an exception, the handle in #execute will convert it to an error and return a "failed" result instead
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public DecorateQueryStringsNormalizer(QueryStringDecorators queryStringDecorator

@Override
public Query normalizeQuery(final Query query, final ParameterProvider parameterProvider) {
// this only makes sense for ElasticsearchQueryString instances, don't touch any other type
if (!(query.query() instanceof ElasticsearchQueryString)) {
return query;
}
return query.toBuilder()
.query(ElasticsearchQueryString.of(this.queryStringDecorators.decorate(query.query().queryString(), parameterProvider, query)))
.filter(normalizeFilter(query.filter(), query, parameterProvider))
Expand Down
Loading