Skip to content

Commit 008a9fc

Browse files
authored
Add Put Query Ruleset API call (#96812)
1 parent 51cc89d commit 008a9fc

File tree

15 files changed

+574
-36
lines changed

15 files changed

+574
-36
lines changed
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"query_ruleset.put": {
3+
"documentation": {
4+
"url": "https://www.elastic.co/guide/en/elasticsearch/reference/master/put-query-ruleset.html",
5+
"description": "Creates or updates a query ruleset."
6+
},
7+
"stability": "experimental",
8+
"visibility": "feature_flag",
9+
"feature_flag": "es.query_rules_feature_flag_enabled",
10+
"headers": {
11+
"accept": [
12+
"application/json"
13+
],
14+
"content_type": [
15+
"application/json"
16+
]
17+
},
18+
"url": {
19+
"paths": [
20+
{
21+
"path": "/_query_rules/{ruleset_id}",
22+
"methods": [
23+
"PUT"
24+
],
25+
"parts": {
26+
"ruleset_id": {
27+
"type": "string",
28+
"description": "The unique identifier of the ruleset to be created or updated."
29+
}
30+
}
31+
}
32+
]
33+
},
34+
"params": {
35+
"create": {
36+
"type": "boolean",
37+
"description": "If true, requires that a query_ruleset with the specified resource_id does not already exist. (default: false)"
38+
}
39+
},
40+
"body": {
41+
"description": "The query ruleset configuration, including `rules`",
42+
"required": true
43+
}
44+
}
45+
}

test/test-clusters/src/main/java/org/elasticsearch/test/cluster/FeatureFlag.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ public enum FeatureFlag {
1818
TIME_SERIES_MODE("es.index_mode_feature_flag_registered=true", Version.fromString("8.0.0"), null),
1919
NEW_RCS_MODE("es.untrusted_remote_cluster_feature_flag_registered=true", Version.fromString("8.5.0"), null),
2020
DLM_ENABLED("es.dlm_feature_flag_enabled=true", Version.fromString("8.8.0"), null),
21-
SYNONYMS_ENABLED("es.synonyms_feature_flag_enabled=true", Version.fromString("8.9.0"), null);
21+
SYNONYMS_ENABLED("es.synonyms_feature_flag_enabled=true", Version.fromString("8.9.0"), null),
22+
QUERY_RULES_ENABLED("es.query_rules_feature_flag_enabled=true", Version.fromString("8.9.0"), null);
2223

2324
public final String systemProperty;
2425
public final Version from;

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/XPackSettings.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,6 @@ public Iterator<Setting<?>> settings() {
107107
Setting.Property.NodeScope
108108
);
109109

110-
/** Setting for enabling or disabling query rules. Defaults to false. */
111-
public static final Setting<Boolean> ENTERPRISE_SEARCH_QUERY_RULES_ENABLED = Setting.boolSetting(
112-
"xpack.ent_search.query_rules.enabled",
113-
false,
114-
Setting.Property.NodeScope
115-
);
116-
117110
/** Setting for enabling or disabling auditing. Defaults to false. */
118111
public static final Setting<Boolean> AUDIT_ENABLED = Setting.boolSetting(
119112
"xpack.security.audit.enabled",

x-pack/plugin/ent-search/qa/rest/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ dependencies {
77

88
restResources {
99
restApi {
10-
include '_common', 'cluster', 'nodes', 'indices', 'index', 'search_application', 'xpack'
10+
include '_common', 'cluster', 'nodes', 'indices', 'index', 'query_ruleset', 'search_application', 'xpack'
1111
}
1212
}
1313

x-pack/plugin/ent-search/qa/rest/roles.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ admin:
22
cluster:
33
- manage_search_application
44
- manage_behavioral_analytics
5+
- manage
56
- monitor
67
indices:
78
- names: [
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
2+
3+
---
4+
'Create Query Ruleset':
5+
- do:
6+
query_ruleset.put:
7+
ruleset_id: test-ruleset
8+
body:
9+
ruleset_id: test-ruleset
10+
rules:
11+
- rule_id: query-rule-id1
12+
type: pinned
13+
criteria:
14+
- type: exact
15+
metadata: query_string
16+
value: elastic
17+
actions:
18+
ids:
19+
- 'id1'
20+
- 'id2'
21+
- rule_id: query-rule-id2
22+
type: pinned
23+
criteria:
24+
- type: exact
25+
metadata: query_string
26+
value: kibana
27+
actions:
28+
docs:
29+
- '_index': 'test-index1'
30+
'_id': 'id3'
31+
- '_index': 'test-index2'
32+
'_id': 'id4'
33+
34+
- match: { result: 'created' }
35+
36+
---
37+
'Create Query Ruleset - Resource already exists':
38+
- do:
39+
query_ruleset.put:
40+
create: true
41+
ruleset_id: test-query-ruleset-recreating
42+
body:
43+
ruleset_id: 'test-query-ruleset-recreating'
44+
rules:
45+
rule_id: 'test-rule-1'
46+
type: 'pinned'
47+
criteria:
48+
type: 'exact'
49+
metadata: 'query_string'
50+
value: 'elastic'
51+
actions:
52+
ids:
53+
- 'id1'
54+
55+
- match: { result: 'created' }
56+
57+
- do:
58+
catch: conflict
59+
query_ruleset.put:
60+
create: true
61+
ruleset_id: test-query-ruleset-recreating
62+
body:
63+
ruleset_id: 'test-query-ruleset-recreating'
64+
rules:
65+
rule_id: 'test-rule-1'
66+
type: 'pinned'
67+
criteria:
68+
type: 'exact'
69+
metadata: 'query_string'
70+
value: 'elastic'
71+
actions:
72+
ids:
73+
- 'id2'
74+
75+
- match: { error.type: 'version_conflict_engine_exception' }
76+
77+
---
78+
'Create Query Ruleset - Insufficient privilege':
79+
- skip:
80+
features: headers
81+
82+
- do:
83+
catch: forbidden
84+
headers: { Authorization: "Basic ZW50c2VhcmNoLXVzZXI6ZW50c2VhcmNoLXVzZXItcGFzc3dvcmQ=" } # user
85+
query_ruleset.put:
86+
ruleset_id: forbidden-query-ruleset
87+
create: true
88+
body:
89+
ruleset_id: 'forbidden-query-ruleset'
90+
rules:
91+
rule_id: 'test-rule-1'
92+
type: 'pinned'
93+
criteria:
94+
type: 'exact'
95+
metadata: 'query_string'
96+
value: 'elastic'
97+
actions:
98+
ids:
99+
- 'id1'
100+
- 'id2'
101+
102+
- match: { error.type: 'security_exception' }

x-pack/plugin/ent-search/src/main/java/module-info.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,5 @@
3030

3131
exports org.elasticsearch.xpack.application.search;
3232
exports org.elasticsearch.xpack.application.search.action;
33+
exports org.elasticsearch.xpack.application.rules.action;
3334
}

x-pack/plugin/ent-search/src/main/java/org/elasticsearch/xpack/application/EnterpriseSearch.java

Lines changed: 51 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.elasticsearch.common.settings.Setting;
2121
import org.elasticsearch.common.settings.Settings;
2222
import org.elasticsearch.common.settings.SettingsFilter;
23+
import org.elasticsearch.common.util.FeatureFlag;
2324
import org.elasticsearch.env.Environment;
2425
import org.elasticsearch.env.NodeEnvironment;
2526
import org.elasticsearch.indices.SystemIndexDescriptor;
@@ -52,6 +53,9 @@
5253
import org.elasticsearch.xpack.application.analytics.action.TransportPutAnalyticsCollectionAction;
5354
import org.elasticsearch.xpack.application.analytics.ingest.AnalyticsEventIngestConfig;
5455
import org.elasticsearch.xpack.application.rules.QueryRulesIndexService;
56+
import org.elasticsearch.xpack.application.rules.action.PutQueryRulesetAction;
57+
import org.elasticsearch.xpack.application.rules.action.RestPutQueryRulesetAction;
58+
import org.elasticsearch.xpack.application.rules.action.TransportPutQueryRulesetAction;
5559
import org.elasticsearch.xpack.application.search.SearchApplicationIndexService;
5660
import org.elasticsearch.xpack.application.search.action.DeleteSearchApplicationAction;
5761
import org.elasticsearch.xpack.application.search.action.GetSearchApplicationAction;
@@ -76,6 +80,7 @@
7680
import org.elasticsearch.xpack.core.action.XPackInfoFeatureAction;
7781
import org.elasticsearch.xpack.core.action.XPackUsageFeatureAction;
7882

83+
import java.util.ArrayList;
7984
import java.util.Arrays;
8085
import java.util.Collection;
8186
import java.util.Collections;
@@ -90,17 +95,18 @@ public class EnterpriseSearch extends Plugin implements ActionPlugin, SystemInde
9095

9196
public static final String BEHAVIORAL_ANALYTICS_API_ENDPOINT = APPLICATION_API_ENDPOINT + "/analytics";
9297

98+
public static final String QUERY_RULES_API_ENDPOINT = "_query_rules";
99+
93100
private static final Logger logger = LogManager.getLogger(EnterpriseSearch.class);
94101

95102
public static final String FEATURE_NAME = "ent_search";
96103

97104
private final boolean enabled;
98105

99-
private final boolean queryRulesEnabled;
106+
private static final FeatureFlag QUERY_RULES_FEATURE_FLAG = new FeatureFlag("query_rules");
100107

101108
public EnterpriseSearch(Settings settings) {
102109
this.enabled = XPackSettings.ENTERPRISE_SEARCH_ENABLED.get(settings);
103-
this.queryRulesEnabled = XPackSettings.ENTERPRISE_SEARCH_QUERY_RULES_ENABLED.get(settings);
104110
}
105111

106112
protected XPackLicenseState getLicenseState() {
@@ -114,20 +120,29 @@ protected XPackLicenseState getLicenseState() {
114120
if (enabled == false) {
115121
return List.of(usageAction, infoAction);
116122
}
117-
return List.of(
118-
new ActionHandler<>(PutAnalyticsCollectionAction.INSTANCE, TransportPutAnalyticsCollectionAction.class),
119-
new ActionHandler<>(GetAnalyticsCollectionAction.INSTANCE, TransportGetAnalyticsCollectionAction.class),
120-
new ActionHandler<>(DeleteAnalyticsCollectionAction.INSTANCE, TransportDeleteAnalyticsCollectionAction.class),
121-
new ActionHandler<>(PostAnalyticsEventAction.INSTANCE, TransportPostAnalyticsEventAction.class),
122-
new ActionHandler<>(DeleteSearchApplicationAction.INSTANCE, TransportDeleteSearchApplicationAction.class),
123-
new ActionHandler<>(GetSearchApplicationAction.INSTANCE, TransportGetSearchApplicationAction.class),
124-
new ActionHandler<>(ListSearchApplicationAction.INSTANCE, TransportListSearchApplicationAction.class),
125-
new ActionHandler<>(PutSearchApplicationAction.INSTANCE, TransportPutSearchApplicationAction.class),
126-
new ActionHandler<>(QuerySearchApplicationAction.INSTANCE, TransportQuerySearchApplicationAction.class),
127-
new ActionHandler<>(RenderSearchApplicationQueryAction.INSTANCE, TransportRenderSearchApplicationQueryAction.class),
128-
usageAction,
129-
infoAction
123+
124+
final List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> actionHandlers = new ArrayList<>(
125+
List.of(
126+
new ActionHandler<>(PutAnalyticsCollectionAction.INSTANCE, TransportPutAnalyticsCollectionAction.class),
127+
new ActionHandler<>(GetAnalyticsCollectionAction.INSTANCE, TransportGetAnalyticsCollectionAction.class),
128+
new ActionHandler<>(DeleteAnalyticsCollectionAction.INSTANCE, TransportDeleteAnalyticsCollectionAction.class),
129+
new ActionHandler<>(PostAnalyticsEventAction.INSTANCE, TransportPostAnalyticsEventAction.class),
130+
new ActionHandler<>(DeleteSearchApplicationAction.INSTANCE, TransportDeleteSearchApplicationAction.class),
131+
new ActionHandler<>(GetSearchApplicationAction.INSTANCE, TransportGetSearchApplicationAction.class),
132+
new ActionHandler<>(ListSearchApplicationAction.INSTANCE, TransportListSearchApplicationAction.class),
133+
new ActionHandler<>(PutSearchApplicationAction.INSTANCE, TransportPutSearchApplicationAction.class),
134+
new ActionHandler<>(QuerySearchApplicationAction.INSTANCE, TransportQuerySearchApplicationAction.class),
135+
new ActionHandler<>(RenderSearchApplicationQueryAction.INSTANCE, TransportRenderSearchApplicationQueryAction.class),
136+
usageAction,
137+
infoAction
138+
)
130139
);
140+
141+
if (QUERY_RULES_FEATURE_FLAG.isEnabled()) {
142+
actionHandlers.add(new ActionHandler<>(PutQueryRulesetAction.INSTANCE, TransportPutQueryRulesetAction.class));
143+
}
144+
145+
return Collections.unmodifiableList(actionHandlers);
131146
}
132147

133148
@Override
@@ -144,18 +159,27 @@ public List<RestHandler> getRestHandlers(
144159
if (enabled == false) {
145160
return Collections.emptyList();
146161
}
147-
return List.of(
148-
new RestGetSearchApplicationAction(getLicenseState()),
149-
new RestListSearchApplicationAction(getLicenseState()),
150-
new RestPutSearchApplicationAction(getLicenseState()),
151-
new RestDeleteSearchApplicationAction(getLicenseState()),
152-
new RestQuerySearchApplicationAction(getLicenseState()),
153-
new RestPutAnalyticsCollectionAction(getLicenseState()),
154-
new RestGetAnalyticsCollectionAction(getLicenseState()),
155-
new RestDeleteAnalyticsCollectionAction(getLicenseState()),
156-
new RestPostAnalyticsEventAction(getLicenseState()),
157-
new RestRenderSearchApplicationQueryAction(getLicenseState())
162+
163+
final List<RestHandler> restHandlers = new ArrayList<>(
164+
List.of(
165+
new RestPutAnalyticsCollectionAction(getLicenseState()),
166+
new RestGetAnalyticsCollectionAction(getLicenseState()),
167+
new RestDeleteAnalyticsCollectionAction(getLicenseState()),
168+
new RestPostAnalyticsEventAction(getLicenseState()),
169+
new RestDeleteSearchApplicationAction(getLicenseState()),
170+
new RestGetSearchApplicationAction(getLicenseState()),
171+
new RestListSearchApplicationAction(getLicenseState()),
172+
new RestPutSearchApplicationAction(getLicenseState()),
173+
new RestQuerySearchApplicationAction(getLicenseState()),
174+
new RestRenderSearchApplicationQueryAction(getLicenseState())
175+
)
158176
);
177+
178+
if (QUERY_RULES_FEATURE_FLAG.isEnabled()) {
179+
restHandlers.add(new RestPutQueryRulesetAction(getLicenseState()));
180+
}
181+
182+
return Collections.unmodifiableList(restHandlers);
159183
}
160184

161185
@Override
@@ -192,7 +216,7 @@ public Collection<Object> createComponents(
192216

193217
@Override
194218
public Collection<SystemIndexDescriptor> getSystemIndexDescriptors(Settings settings) {
195-
if (queryRulesEnabled) {
219+
if (QUERY_RULES_FEATURE_FLAG.isEnabled()) {
196220
return Arrays.asList(
197221
SearchApplicationIndexService.getSystemIndexDescriptor(),
198222
QueryRulesIndexService.getSystemIndexDescriptor()

0 commit comments

Comments
 (0)