Skip to content

Commit 76236dc

Browse files
Autoscaling decider and decision service (elastic#59005)
Split the autoscaling decider into a service and configuration in order to enable having additional context information available in the service. Added AutoscalingDeciderContext holding generic information all deciders are expected to need. Implemented GET _autoscaling/decision
1 parent a2d5bfc commit 76236dc

File tree

17 files changed

+453
-51
lines changed

17 files changed

+453
-51
lines changed

docs/reference/autoscaling/apis/get-autoscaling-policy.asciidoc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@ PUT /_autoscaling/policy/my_autoscaling_policy
2525
--------------------------------------------------
2626
// TESTSETUP
2727

28+
//////////////////////////
29+
30+
[source,console]
31+
--------------------------------------------------
32+
DELETE /_autoscaling/policy/my_autoscaling_policy
33+
--------------------------------------------------
34+
// TEST
35+
// TEARDOWN
36+
37+
//////////////////////////
38+
2839
[source,console]
2940
--------------------------------------------------
3041
GET /_autoscaling/policy/<name>

docs/reference/autoscaling/apis/put-autoscaling-policy.asciidoc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ PUT /_autoscaling/policy/<name>
2525
--------------------------------------------------
2626
// TEST[s/<name>/name/]
2727

28+
//////////////////////////
29+
30+
[source,console]
31+
--------------------------------------------------
32+
DELETE /_autoscaling/policy/name
33+
--------------------------------------------------
34+
// TEST[continued]
35+
36+
//////////////////////////
37+
2838
[[autoscaling-put-autoscaling-policy-prereqs]]
2939
==== {api-prereq-title}
3040

@@ -65,3 +75,13 @@ The API returns the following result:
6575
"acknowledged": true
6676
}
6777
--------------------------------------------------
78+
79+
//////////////////////////
80+
81+
[source,console]
82+
--------------------------------------------------
83+
DELETE /_autoscaling/policy/my_autoscaling_policy
84+
--------------------------------------------------
85+
// TEST[continued]
86+
87+
//////////////////////////
Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,31 @@
11
---
2-
"Test get autoscaling decision":
2+
"Test get empty autoscaling decision":
33
- do:
44
autoscaling.get_autoscaling_decision: {}
55

66
- match: { "decisions": [] }
7+
8+
---
9+
"Test get always autoscaling decision":
10+
- do:
11+
autoscaling.put_autoscaling_policy:
12+
name: my_autoscaling_policy
13+
body:
14+
policy:
15+
deciders:
16+
always: {}
17+
18+
- match: { "acknowledged": true }
19+
20+
- do:
21+
autoscaling.get_autoscaling_decision: {}
22+
23+
- match: { decisions.0.my_autoscaling_policy.decision: scale_up }
24+
- match: { decisions.0.my_autoscaling_policy.decisions.0.name: always }
25+
- match: { decisions.0.my_autoscaling_policy.decisions.0.type: scale_up }
26+
- match: { decisions.0.my_autoscaling_policy.decisions.0.reason: always }
27+
28+
# test cleanup
29+
- do:
30+
autoscaling.delete_autoscaling_policy:
31+
name: my_autoscaling_policy

x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/Autoscaling.java

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,17 @@
66

77
package org.elasticsearch.xpack.autoscaling;
88

9+
import org.apache.logging.log4j.LogManager;
10+
import org.apache.logging.log4j.Logger;
911
import org.elasticsearch.Build;
1012
import org.elasticsearch.action.ActionRequest;
1113
import org.elasticsearch.action.ActionResponse;
14+
import org.elasticsearch.client.Client;
1215
import org.elasticsearch.cluster.NamedDiff;
1316
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
1417
import org.elasticsearch.cluster.metadata.Metadata;
1518
import org.elasticsearch.cluster.node.DiscoveryNodes;
19+
import org.elasticsearch.cluster.service.ClusterService;
1620
import org.elasticsearch.common.ParseField;
1721
import org.elasticsearch.common.io.stream.NamedWriteableRegistry;
1822
import org.elasticsearch.common.settings.ClusterSettings;
@@ -21,11 +25,18 @@
2125
import org.elasticsearch.common.settings.Settings;
2226
import org.elasticsearch.common.settings.SettingsFilter;
2327
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
28+
import org.elasticsearch.env.Environment;
29+
import org.elasticsearch.env.NodeEnvironment;
2430
import org.elasticsearch.license.XPackLicenseState;
2531
import org.elasticsearch.plugins.ActionPlugin;
32+
import org.elasticsearch.plugins.ExtensiblePlugin;
2633
import org.elasticsearch.plugins.Plugin;
34+
import org.elasticsearch.repositories.RepositoriesService;
2735
import org.elasticsearch.rest.RestController;
2836
import org.elasticsearch.rest.RestHandler;
37+
import org.elasticsearch.script.ScriptService;
38+
import org.elasticsearch.threadpool.ThreadPool;
39+
import org.elasticsearch.watcher.ResourceWatcherService;
2940
import org.elasticsearch.xpack.autoscaling.action.DeleteAutoscalingPolicyAction;
3041
import org.elasticsearch.xpack.autoscaling.action.GetAutoscalingDecisionAction;
3142
import org.elasticsearch.xpack.autoscaling.action.GetAutoscalingPolicyAction;
@@ -34,22 +45,29 @@
3445
import org.elasticsearch.xpack.autoscaling.action.TransportGetAutoscalingDecisionAction;
3546
import org.elasticsearch.xpack.autoscaling.action.TransportGetAutoscalingPolicyAction;
3647
import org.elasticsearch.xpack.autoscaling.action.TransportPutAutoscalingPolicyAction;
37-
import org.elasticsearch.xpack.autoscaling.decision.AlwaysAutoscalingDecider;
38-
import org.elasticsearch.xpack.autoscaling.decision.AutoscalingDecider;
48+
import org.elasticsearch.xpack.autoscaling.decision.AlwaysAutoscalingDeciderConfiguration;
49+
import org.elasticsearch.xpack.autoscaling.decision.AlwaysAutoscalingDeciderService;
50+
import org.elasticsearch.xpack.autoscaling.decision.AutoscalingDeciderConfiguration;
51+
import org.elasticsearch.xpack.autoscaling.decision.AutoscalingDeciderService;
52+
import org.elasticsearch.xpack.autoscaling.decision.AutoscalingDecisionService;
3953
import org.elasticsearch.xpack.autoscaling.rest.RestDeleteAutoscalingPolicyHandler;
4054
import org.elasticsearch.xpack.autoscaling.rest.RestGetAutoscalingDecisionHandler;
4155
import org.elasticsearch.xpack.autoscaling.rest.RestGetAutoscalingPolicyHandler;
4256
import org.elasticsearch.xpack.autoscaling.rest.RestPutAutoscalingPolicyHandler;
4357
import org.elasticsearch.xpack.core.XPackPlugin;
4458

59+
import java.util.ArrayList;
60+
import java.util.Collection;
4561
import java.util.List;
62+
import java.util.Set;
4663
import java.util.function.Supplier;
64+
import java.util.stream.Collectors;
4765

4866
/**
4967
* Container class for autoscaling functionality.
5068
*/
51-
public class Autoscaling extends Plugin implements ActionPlugin {
52-
69+
public class Autoscaling extends Plugin implements ActionPlugin, ExtensiblePlugin, AutoscalingExtension {
70+
private static final Logger logger = LogManager.getLogger(AutoscalingExtension.class);
5371
private static final Boolean AUTOSCALING_FEATURE_FLAG_REGISTERED;
5472

5573
static {
@@ -78,8 +96,11 @@ public class Autoscaling extends Plugin implements ActionPlugin {
7896

7997
private final boolean enabled;
8098

99+
private final List<AutoscalingExtension> autoscalingExtensions;
100+
81101
public Autoscaling(final Settings settings) {
82102
this.enabled = AUTOSCALING_ENABLED_SETTING.get(settings);
103+
this.autoscalingExtensions = new ArrayList<>(org.elasticsearch.common.collect.List.of(this));
83104
}
84105

85106
/**
@@ -100,6 +121,23 @@ boolean isSnapshot() {
100121
return Build.CURRENT.isSnapshot();
101122
}
102123

124+
@Override
125+
public Collection<Object> createComponents(
126+
Client client,
127+
ClusterService clusterService,
128+
ThreadPool threadPool,
129+
ResourceWatcherService resourceWatcherService,
130+
ScriptService scriptService,
131+
NamedXContentRegistry xContentRegistry,
132+
Environment environment,
133+
NodeEnvironment nodeEnvironment,
134+
NamedWriteableRegistry namedWriteableRegistry,
135+
IndexNameExpressionResolver indexNameExpressionResolver,
136+
Supplier<RepositoriesService> repositoriesServiceSupplier
137+
) {
138+
return org.elasticsearch.common.collect.List.of(new AutoscalingDecisionService.Holder(this));
139+
}
140+
103141
@Override
104142
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
105143
if (enabled) {
@@ -141,7 +179,11 @@ public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
141179
return org.elasticsearch.common.collect.List.of(
142180
new NamedWriteableRegistry.Entry(Metadata.Custom.class, AutoscalingMetadata.NAME, AutoscalingMetadata::new),
143181
new NamedWriteableRegistry.Entry(NamedDiff.class, AutoscalingMetadata.NAME, AutoscalingMetadata.AutoscalingMetadataDiff::new),
144-
new NamedWriteableRegistry.Entry(AutoscalingDecider.class, AlwaysAutoscalingDecider.NAME, AlwaysAutoscalingDecider::new)
182+
new NamedWriteableRegistry.Entry(
183+
AutoscalingDeciderConfiguration.class,
184+
AlwaysAutoscalingDeciderConfiguration.NAME,
185+
AlwaysAutoscalingDeciderConfiguration::new
186+
)
145187
);
146188
}
147189

@@ -150,9 +192,9 @@ public List<NamedXContentRegistry.Entry> getNamedXContent() {
150192
return org.elasticsearch.common.collect.List.of(
151193
new NamedXContentRegistry.Entry(Metadata.Custom.class, new ParseField(AutoscalingMetadata.NAME), AutoscalingMetadata::parse),
152194
new NamedXContentRegistry.Entry(
153-
AutoscalingDecider.class,
154-
new ParseField(AlwaysAutoscalingDecider.NAME),
155-
AlwaysAutoscalingDecider::parse
195+
AutoscalingDeciderConfiguration.class,
196+
new ParseField(AlwaysAutoscalingDeciderConfiguration.NAME),
197+
AlwaysAutoscalingDeciderConfiguration::parse
156198
)
157199
);
158200
}
@@ -161,4 +203,17 @@ protected XPackLicenseState getLicenseState() {
161203
return XPackPlugin.getSharedLicenseState();
162204
}
163205

206+
@Override
207+
public void loadExtensions(ExtensionLoader loader) {
208+
loader.loadExtensions(AutoscalingExtension.class).forEach(autoscalingExtensions::add);
209+
}
210+
211+
@Override
212+
public Collection<AutoscalingDeciderService<? extends AutoscalingDeciderConfiguration>> deciders() {
213+
return org.elasticsearch.common.collect.List.of(new AlwaysAutoscalingDeciderService());
214+
}
215+
216+
public Set<AutoscalingDeciderService<? extends AutoscalingDeciderConfiguration>> createDeciderServices() {
217+
return autoscalingExtensions.stream().flatMap(p -> p.deciders().stream()).collect(Collectors.toSet());
218+
}
164219
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.autoscaling;
8+
9+
import org.elasticsearch.xpack.autoscaling.decision.AutoscalingDeciderConfiguration;
10+
import org.elasticsearch.xpack.autoscaling.decision.AutoscalingDeciderService;
11+
12+
import java.util.Collection;
13+
14+
public interface AutoscalingExtension {
15+
/**
16+
* Get the list of decider services for this plugin. This is called after createComponents has been called.
17+
* @return list of decider services
18+
*/
19+
Collection<AutoscalingDeciderService<? extends AutoscalingDeciderConfiguration>> deciders();
20+
}

x-pack/plugin/autoscaling/src/main/java/org/elasticsearch/xpack/autoscaling/action/TransportGetAutoscalingDecisionAction.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,24 @@
1717
import org.elasticsearch.common.io.stream.StreamInput;
1818
import org.elasticsearch.threadpool.ThreadPool;
1919
import org.elasticsearch.transport.TransportService;
20+
import org.elasticsearch.xpack.autoscaling.decision.AutoscalingDecisionService;
2021

2122
import java.io.IOException;
22-
import java.util.Collections;
23-
import java.util.TreeMap;
2423

2524
public class TransportGetAutoscalingDecisionAction extends TransportMasterNodeAction<
2625
GetAutoscalingDecisionAction.Request,
2726
GetAutoscalingDecisionAction.Response> {
2827

28+
private final AutoscalingDecisionService decisionService;
29+
2930
@Inject
3031
public TransportGetAutoscalingDecisionAction(
3132
final TransportService transportService,
3233
final ClusterService clusterService,
3334
final ThreadPool threadPool,
3435
final ActionFilters actionFilters,
35-
final IndexNameExpressionResolver indexNameExpressionResolver
36+
final IndexNameExpressionResolver indexNameExpressionResolver,
37+
final AutoscalingDecisionService.Holder decisionServiceHolder
3638
) {
3739
super(
3840
GetAutoscalingDecisionAction.NAME,
@@ -43,6 +45,8 @@ public TransportGetAutoscalingDecisionAction(
4345
GetAutoscalingDecisionAction.Request::new,
4446
indexNameExpressionResolver
4547
);
48+
this.decisionService = decisionServiceHolder.get();
49+
assert this.decisionService != null;
4650
}
4751

4852
@Override
@@ -61,7 +65,7 @@ protected void masterOperation(
6165
final ClusterState state,
6266
final ActionListener<GetAutoscalingDecisionAction.Response> listener
6367
) {
64-
listener.onResponse(new GetAutoscalingDecisionAction.Response(Collections.unmodifiableSortedMap(new TreeMap<>())));
68+
listener.onResponse(new GetAutoscalingDecisionAction.Response(decisionService.decide(state)));
6569
}
6670

6771
@Override
Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,23 @@
1414

1515
import java.io.IOException;
1616

17-
public class AlwaysAutoscalingDecider implements AutoscalingDecider {
17+
public class AlwaysAutoscalingDeciderConfiguration implements AutoscalingDeciderConfiguration {
1818

1919
public static final String NAME = "always";
2020

21-
private static final ObjectParser<AlwaysAutoscalingDecider, Void> PARSER = new ObjectParser<>(NAME, AlwaysAutoscalingDecider::new);
21+
private static final ObjectParser<AlwaysAutoscalingDeciderConfiguration, Void> PARSER = new ObjectParser<>(
22+
NAME,
23+
AlwaysAutoscalingDeciderConfiguration::new
24+
);
2225

23-
public static AlwaysAutoscalingDecider parse(final XContentParser parser) {
26+
public static AlwaysAutoscalingDeciderConfiguration parse(final XContentParser parser) {
2427
return PARSER.apply(parser, null);
2528
}
2629

27-
public AlwaysAutoscalingDecider() {}
30+
public AlwaysAutoscalingDeciderConfiguration() {}
2831

2932
@SuppressWarnings("unused")
30-
public AlwaysAutoscalingDecider(final StreamInput in) {
33+
public AlwaysAutoscalingDeciderConfiguration(final StreamInput in) {
3134

3235
}
3336

@@ -36,11 +39,6 @@ public String name() {
3639
return NAME;
3740
}
3841

39-
@Override
40-
public AutoscalingDecision scale() {
41-
return new AutoscalingDecision(NAME, AutoscalingDecisionType.SCALE_UP, "always");
42-
}
43-
4442
@Override
4543
public String getWriteableName() {
4644
return NAME;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
7+
package org.elasticsearch.xpack.autoscaling.decision;
8+
9+
import org.elasticsearch.common.inject.Inject;
10+
11+
public class AlwaysAutoscalingDeciderService implements AutoscalingDeciderService<AlwaysAutoscalingDeciderConfiguration> {
12+
13+
@Inject
14+
public AlwaysAutoscalingDeciderService() {}
15+
16+
@Override
17+
public String name() {
18+
return AlwaysAutoscalingDeciderConfiguration.NAME;
19+
}
20+
21+
@Override
22+
public AutoscalingDecision scale(AlwaysAutoscalingDeciderConfiguration decider, AutoscalingDeciderContext context) {
23+
return new AutoscalingDecision(AlwaysAutoscalingDeciderConfiguration.NAME, AutoscalingDecisionType.SCALE_UP, "always");
24+
}
25+
}
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,12 @@
1212
/**
1313
* Represents an autoscaling decider, a component that determines whether or not to scale.
1414
*/
15-
public interface AutoscalingDecider extends ToXContentObject, NamedWriteable {
15+
public interface AutoscalingDeciderConfiguration extends ToXContentObject, NamedWriteable {
1616

1717
/**
1818
* The name of the autoscaling decider.
1919
*
2020
* @return the name
2121
*/
2222
String name();
23-
24-
/**
25-
* Whether or not to scale based on the current state.
26-
*
27-
* @return the autoscaling decision
28-
*/
29-
AutoscalingDecision scale();
30-
3123
}

0 commit comments

Comments
 (0)