Skip to content

Commit 7d87d23

Browse files
Configure Autoscaling deciders using settings (#64428) (#65390)
Autoscaling deciders are now configured using settings, allowing an easy way to add default values as well as building upon the existing setting code. This makes it easier to add new deciders since there is no need for a separate configuration object.
1 parent da77dcd commit 7d87d23

26 files changed

+427
-631
lines changed

x-pack/plugin/autoscaling/qa/rest/src/yamlRestTest/resources/rest-api-spec/test/autoscaling/put_autoscaling_policy.yml

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@
6262
- do:
6363
autoscaling.delete_autoscaling_policy:
6464
name: my_autoscaling_policy
65+
66+
---
67+
"Test put autoscaling policy with non-existent roles":
68+
- do:
69+
catch: bad_request
70+
autoscaling.put_autoscaling_policy:
71+
name: my_autoscaling_policy
72+
body:
73+
roles: [ non-existing ]
74+
75+
---
76+
"Test add autoscaling policy with no roles":
77+
- do:
78+
catch: bad_request
79+
autoscaling.put_autoscaling_policy:
80+
name: my_autoscaling_policy
81+
body: {}
82+
6583
---
6684
"Test put autoscaling policy with non-existent decider":
6785
- do:
@@ -74,18 +92,23 @@
7492
does_not_exist: {}
7593

7694
---
77-
"Test put autoscaling policy with non-existent roles":
95+
"Test put autoscaling policy with non-existent decider setting":
7896
- do:
7997
catch: bad_request
8098
autoscaling.put_autoscaling_policy:
8199
name: my_autoscaling_policy
82100
body:
83-
roles: [ non-existing ]
101+
deciders:
102+
fixed:
103+
does_not_exist: 0
84104

85105
---
86-
"Test add autoscaling policy with no roles":
106+
"Test put autoscaling policy with bad setting value":
87107
- do:
88108
catch: bad_request
89109
autoscaling.put_autoscaling_policy:
90110
name: my_autoscaling_policy
91-
body: {}
111+
body:
112+
policy:
113+
fixed:
114+
storage: bad

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

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,8 @@
4444
import org.elasticsearch.xpack.autoscaling.action.TransportGetAutoscalingPolicyAction;
4545
import org.elasticsearch.xpack.autoscaling.action.TransportPutAutoscalingPolicyAction;
4646
import org.elasticsearch.xpack.autoscaling.capacity.AutoscalingCalculateCapacityService;
47-
import org.elasticsearch.xpack.autoscaling.capacity.AutoscalingDeciderConfiguration;
4847
import org.elasticsearch.xpack.autoscaling.capacity.AutoscalingDeciderResult;
4948
import org.elasticsearch.xpack.autoscaling.capacity.AutoscalingDeciderService;
50-
import org.elasticsearch.xpack.autoscaling.capacity.FixedAutoscalingDeciderConfiguration;
5149
import org.elasticsearch.xpack.autoscaling.capacity.FixedAutoscalingDeciderService;
5250
import org.elasticsearch.xpack.autoscaling.rest.RestDeleteAutoscalingPolicyHandler;
5351
import org.elasticsearch.xpack.autoscaling.rest.RestGetAutoscalingCapacityHandler;
@@ -178,14 +176,9 @@ public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
178176
return org.elasticsearch.common.collect.List.of(
179177
new NamedWriteableRegistry.Entry(Metadata.Custom.class, AutoscalingMetadata.NAME, AutoscalingMetadata::new),
180178
new NamedWriteableRegistry.Entry(NamedDiff.class, AutoscalingMetadata.NAME, AutoscalingMetadata.AutoscalingMetadataDiff::new),
181-
new NamedWriteableRegistry.Entry(
182-
AutoscalingDeciderConfiguration.class,
183-
FixedAutoscalingDeciderConfiguration.NAME,
184-
FixedAutoscalingDeciderConfiguration::new
185-
),
186179
new NamedWriteableRegistry.Entry(
187180
AutoscalingDeciderResult.Reason.class,
188-
FixedAutoscalingDeciderConfiguration.NAME,
181+
FixedAutoscalingDeciderService.NAME,
189182
FixedAutoscalingDeciderService.FixedReason::new
190183
)
191184
);
@@ -194,12 +187,7 @@ public List<NamedWriteableRegistry.Entry> getNamedWriteables() {
194187
@Override
195188
public List<NamedXContentRegistry.Entry> getNamedXContent() {
196189
return org.elasticsearch.common.collect.List.of(
197-
new NamedXContentRegistry.Entry(Metadata.Custom.class, new ParseField(AutoscalingMetadata.NAME), AutoscalingMetadata::parse),
198-
new NamedXContentRegistry.Entry(
199-
AutoscalingDeciderConfiguration.class,
200-
new ParseField(FixedAutoscalingDeciderConfiguration.NAME),
201-
FixedAutoscalingDeciderConfiguration::parse
202-
)
190+
new NamedXContentRegistry.Entry(Metadata.Custom.class, new ParseField(AutoscalingMetadata.NAME), AutoscalingMetadata::parse)
203191
);
204192
}
205193

@@ -213,11 +201,11 @@ public void loadExtensions(ExtensionLoader loader) {
213201
}
214202

215203
@Override
216-
public Collection<AutoscalingDeciderService<? extends AutoscalingDeciderConfiguration>> deciders() {
204+
public Collection<AutoscalingDeciderService> deciders() {
217205
return org.elasticsearch.common.collect.List.of(new FixedAutoscalingDeciderService());
218206
}
219207

220-
public Set<AutoscalingDeciderService<? extends AutoscalingDeciderConfiguration>> createDeciderServices() {
208+
public Set<AutoscalingDeciderService> createDeciderServices() {
221209
return autoscalingExtensions.stream().flatMap(p -> p.deciders().stream()).collect(Collectors.toSet());
222210
}
223211
}

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
package org.elasticsearch.xpack.autoscaling;
88

9-
import org.elasticsearch.xpack.autoscaling.capacity.AutoscalingDeciderConfiguration;
109
import org.elasticsearch.xpack.autoscaling.capacity.AutoscalingDeciderService;
1110

1211
import java.util.Collection;
@@ -16,5 +15,5 @@ public interface AutoscalingExtension {
1615
* Get the list of decider services for this plugin. This is called after createComponents has been called.
1716
* @return list of decider services
1817
*/
19-
Collection<AutoscalingDeciderService<? extends AutoscalingDeciderConfiguration>> deciders();
18+
Collection<AutoscalingDeciderService> deciders();
2019
}
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.action;
8+
9+
import org.elasticsearch.xpack.autoscaling.policy.AutoscalingPolicy;
10+
11+
/**
12+
* Validator to check autoscaling policies
13+
*/
14+
public interface PolicyValidator {
15+
/**
16+
* Validate the given policy, e.g., check decider names, setting names and values.
17+
* @param policy the policy to validate
18+
*/
19+
void validate(AutoscalingPolicy policy);
20+
}

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

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@
1515
import org.elasticsearch.common.Strings;
1616
import org.elasticsearch.common.io.stream.StreamInput;
1717
import org.elasticsearch.common.io.stream.StreamOutput;
18+
import org.elasticsearch.common.settings.Settings;
1819
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
1920
import org.elasticsearch.common.xcontent.XContentParser;
20-
import org.elasticsearch.xpack.autoscaling.capacity.AutoscalingDeciderConfiguration;
2121
import org.elasticsearch.xpack.autoscaling.policy.AutoscalingPolicy;
2222

2323
import java.io.IOException;
2424
import java.util.AbstractMap;
25-
import java.util.ArrayList;
25+
import java.util.Collections;
2626
import java.util.Collections;
2727
import java.util.List;
2828
import java.util.Map;
@@ -31,7 +31,6 @@
3131
import java.util.SortedSet;
3232
import java.util.TreeMap;
3333
import java.util.TreeSet;
34-
import java.util.function.Function;
3534
import java.util.function.Predicate;
3635
import java.util.stream.Collectors;
3736

@@ -54,9 +53,9 @@ public static class Request extends AcknowledgedRequest<Request> {
5453
@SuppressWarnings("unchecked")
5554
final List<String> roles = (List<String>) c[0];
5655
@SuppressWarnings("unchecked")
57-
List<Map.Entry<String, AutoscalingDeciderConfiguration>> deciders =
56+
List<Map.Entry<String, Settings>> deciders =
5857
// help spotless format this
59-
(List<Map.Entry<String, AutoscalingDeciderConfiguration>>) c[1];
58+
(List<Map.Entry<String, Settings>>) c[1];
6059
return new Request(
6160
name,
6261
roles != null ? Collections.unmodifiableSortedSet(new TreeSet<>(roles)) : null,
@@ -66,47 +65,43 @@ public static class Request extends AcknowledgedRequest<Request> {
6665
);
6766
});
6867
PARSER.declareStringArray(ConstructingObjectParser.optionalConstructorArg(), AutoscalingPolicy.ROLES_FIELD);
69-
PARSER.declareNamedObjects(
70-
ConstructingObjectParser.optionalConstructorArg(),
71-
(p, c, n) -> new AbstractMap.SimpleEntry<>(n, p.namedObject(AutoscalingDeciderConfiguration.class, n, null)),
72-
AutoscalingPolicy.DECIDERS_FIELD
73-
);
68+
PARSER.declareNamedObjects(ConstructingObjectParser.optionalConstructorArg(), (p, c, n) -> {
69+
p.nextToken();
70+
return new AbstractMap.SimpleEntry<>(n, Settings.fromXContent(p));
71+
}, AutoscalingPolicy.DECIDERS_FIELD);
7472
}
7573

7674
private final String name;
7775
private final SortedSet<String> roles;
78-
private final SortedMap<String, AutoscalingDeciderConfiguration> deciders;
76+
private final SortedMap<String, Settings> deciders;
7977

8078
public static Request parse(final XContentParser parser, final String name) {
8179
return PARSER.apply(parser, name);
8280
}
8381

84-
public Request(
85-
final String name,
86-
final SortedSet<String> roles,
87-
final SortedMap<String, AutoscalingDeciderConfiguration> deciders
88-
) {
82+
public Request(final String name, final SortedSet<String> roles, final SortedMap<String, Settings> deciders) {
8983
this.name = name;
9084
this.roles = roles;
9185
this.deciders = deciders;
9286
}
9387

9488
public Request(final StreamInput in) throws IOException {
9589
super(in);
96-
name = in.readString();
90+
this.name = in.readString();
9791
if (in.readBoolean()) {
98-
roles = Collections.unmodifiableSortedSet(new TreeSet<>(in.readSet(StreamInput::readString)));
92+
this.roles = Collections.unmodifiableSortedSet(new TreeSet<>(in.readSet(StreamInput::readString)));
9993
} else {
100-
roles = null;
94+
this.roles = null;
10195
}
10296
if (in.readBoolean()) {
103-
deciders = new TreeMap<>(
104-
in.readNamedWriteableList(AutoscalingDeciderConfiguration.class)
105-
.stream()
106-
.collect(Collectors.toMap(AutoscalingDeciderConfiguration::name, Function.identity()))
107-
);
97+
int deciderCount = in.readInt();
98+
SortedMap<String, Settings> deciders = new TreeMap<>();
99+
for (int i = 0; i < deciderCount; ++i) {
100+
deciders.put(in.readString(), Settings.readSettingsFromStream(in));
101+
}
102+
this.deciders = Collections.unmodifiableSortedMap(deciders);
108103
} else {
109-
deciders = null;
104+
this.deciders = null;
110105
}
111106
}
112107

@@ -122,7 +117,11 @@ public void writeTo(final StreamOutput out) throws IOException {
122117
}
123118
if (deciders != null) {
124119
out.writeBoolean(true);
125-
out.writeNamedWriteableList(Collections.unmodifiableList(new ArrayList<>(deciders.values())));
120+
out.writeInt(deciders.size());
121+
for (Map.Entry<String, Settings> entry : deciders.entrySet()) {
122+
out.writeString(entry.getKey());
123+
Settings.writeSettingsToStream(entry.getValue(), out);
124+
}
126125
} else {
127126
out.writeBoolean(false);
128127
}
@@ -136,7 +135,7 @@ public SortedSet<String> roles() {
136135
return roles;
137136
}
138137

139-
public SortedMap<String, AutoscalingDeciderConfiguration> deciders() {
138+
public SortedMap<String, Settings> deciders() {
140139
return deciders;
141140
}
142141

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.elasticsearch.threadpool.ThreadPool;
2424
import org.elasticsearch.transport.TransportService;
2525
import org.elasticsearch.xpack.autoscaling.AutoscalingMetadata;
26+
import org.elasticsearch.xpack.autoscaling.capacity.AutoscalingCalculateCapacityService;
2627
import org.elasticsearch.xpack.autoscaling.policy.AutoscalingPolicy;
2728
import org.elasticsearch.xpack.autoscaling.policy.AutoscalingPolicyMetadata;
2829

@@ -34,13 +35,27 @@ public class TransportPutAutoscalingPolicyAction extends AcknowledgedTransportMa
3435

3536
private static final Logger logger = LogManager.getLogger(TransportPutAutoscalingPolicyAction.class);
3637

38+
private final PolicyValidator policyValidator;
39+
3740
@Inject
3841
public TransportPutAutoscalingPolicyAction(
3942
final TransportService transportService,
4043
final ClusterService clusterService,
4144
final ThreadPool threadPool,
4245
final ActionFilters actionFilters,
43-
final IndexNameExpressionResolver indexNameExpressionResolver
46+
final IndexNameExpressionResolver indexNameExpressionResolver,
47+
final AutoscalingCalculateCapacityService.Holder policyValidatorHolder
48+
) {
49+
this(transportService, clusterService, threadPool, actionFilters, indexNameExpressionResolver, policyValidatorHolder.get());
50+
}
51+
52+
TransportPutAutoscalingPolicyAction(
53+
final TransportService transportService,
54+
final ClusterService clusterService,
55+
final ThreadPool threadPool,
56+
final ActionFilters actionFilters,
57+
final IndexNameExpressionResolver indexNameExpressionResolver,
58+
final PolicyValidator policyValidator
4459
) {
4560
super(
4661
PutAutoscalingPolicyAction.NAME,
@@ -52,6 +67,7 @@ public TransportPutAutoscalingPolicyAction(
5267
indexNameExpressionResolver,
5368
ThreadPool.Names.SAME
5469
);
70+
this.policyValidator = policyValidator;
5571
}
5672

5773
@Override
@@ -63,7 +79,7 @@ protected void masterOperation(
6379
clusterService.submitStateUpdateTask("put-autoscaling-policy", new AckedClusterStateUpdateTask(request, listener) {
6480
@Override
6581
public ClusterState execute(final ClusterState currentState) {
66-
return putAutoscalingPolicy(currentState, request, logger);
82+
return putAutoscalingPolicy(currentState, request, policyValidator, logger);
6783
}
6884
});
6985
}
@@ -76,6 +92,7 @@ protected ClusterBlockException checkBlock(final PutAutoscalingPolicyAction.Requ
7692
static ClusterState putAutoscalingPolicy(
7793
final ClusterState currentState,
7894
final PutAutoscalingPolicyAction.Request request,
95+
final PolicyValidator policyValidator,
7996
final Logger logger
8097
) {
8198
// we allow putting policies with roles that not all nodes in the cluster may understand currently (but the current master must
@@ -110,6 +127,8 @@ static ClusterState putAutoscalingPolicy(
110127
);
111128
}
112129

130+
policyValidator.validate(updatedPolicy);
131+
113132
final SortedMap<String, AutoscalingPolicyMetadata> newPolicies = new TreeMap<>(currentMetadata.policies());
114133
final AutoscalingPolicyMetadata newPolicyMetadata = new AutoscalingPolicyMetadata(updatedPolicy);
115134
final AutoscalingPolicyMetadata oldPolicyMetadata = newPolicies.put(request.name(), newPolicyMetadata);

0 commit comments

Comments
 (0)