Allow empty configuration for SLM policies (#44465)

* Allow empty configuration for SLM policies

When putting or updating a snapshot lifecycle policy it was not possible
to elide the `config` map. This commit makes the configuration optional,
the same way that it is when taking a snapshot.

Relates to #38461

* Add Objects.requireNonNull for required parts of the policy
This commit is contained in:
Lee Hinman 2019-07-18 16:19:49 -06:00 committed by Lee Hinman
parent fe2ef66e45
commit 3001f7941f
5 changed files with 32 additions and 21 deletions

View File

@ -19,7 +19,7 @@
package org.elasticsearch.client.snapshotlifecycle;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
@ -43,8 +43,6 @@ public class SnapshotLifecyclePolicy implements ToXContentObject {
private static final ParseField SCHEDULE = new ParseField("schedule");
private static final ParseField REPOSITORY = new ParseField("repository");
private static final ParseField CONFIG = new ParseField("config");
private static final IndexNameExpressionResolver.DateMathExpressionResolver DATE_MATH_RESOLVER =
new IndexNameExpressionResolver.DateMathExpressionResolver();
@SuppressWarnings("unchecked")
private static final ConstructingObjectParser<SnapshotLifecyclePolicy, String> PARSER =
@ -61,11 +59,11 @@ public class SnapshotLifecyclePolicy implements ToXContentObject {
PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME);
PARSER.declareString(ConstructingObjectParser.constructorArg(), SCHEDULE);
PARSER.declareString(ConstructingObjectParser.constructorArg(), REPOSITORY);
PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> p.map(), CONFIG);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> p.map(), CONFIG);
}
public SnapshotLifecyclePolicy(final String id, final String name, final String schedule,
final String repository, Map<String, Object> configuration) {
final String repository, @Nullable Map<String, Object> configuration) {
this.id = Objects.requireNonNull(id);
this.name = name;
this.schedule = schedule;
@ -89,6 +87,7 @@ public class SnapshotLifecyclePolicy implements ToXContentObject {
return this.repository;
}
@Nullable
public Map<String, Object> getConfig() {
return this.configuration;
}
@ -103,7 +102,9 @@ public class SnapshotLifecyclePolicy implements ToXContentObject {
builder.field(NAME.getPreferredName(), this.name);
builder.field(SCHEDULE.getPreferredName(), this.schedule);
builder.field(REPOSITORY.getPreferredName(), this.repository);
builder.field(CONFIG.getPreferredName(), this.configuration);
if (this.configuration != null) {
builder.field(CONFIG.getPreferredName(), this.configuration);
}
builder.endObject();
return builder;
}

View File

@ -15,6 +15,7 @@ import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.Diffable;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver.Context;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.UUIDs;
@ -76,15 +77,15 @@ public class SnapshotLifecyclePolicy extends AbstractDiffable<SnapshotLifecycleP
PARSER.declareString(ConstructingObjectParser.constructorArg(), NAME);
PARSER.declareString(ConstructingObjectParser.constructorArg(), SCHEDULE);
PARSER.declareString(ConstructingObjectParser.constructorArg(), REPOSITORY);
PARSER.declareObject(ConstructingObjectParser.constructorArg(), (p, c) -> p.map(), CONFIG);
PARSER.declareObject(ConstructingObjectParser.optionalConstructorArg(), (p, c) -> p.map(), CONFIG);
}
public SnapshotLifecyclePolicy(final String id, final String name, final String schedule,
final String repository, Map<String, Object> configuration) {
this.id = Objects.requireNonNull(id);
this.name = name;
this.schedule = schedule;
this.repository = repository;
final String repository, @Nullable Map<String, Object> configuration) {
this.id = Objects.requireNonNull(id, "policy id is required");
this.name = Objects.requireNonNull(name, "policy snapshot name is required");
this.schedule = Objects.requireNonNull(schedule, "policy schedule is required");
this.repository = Objects.requireNonNull(repository, "policy snapshot repository is required");
this.configuration = configuration;
}
@ -112,6 +113,7 @@ public class SnapshotLifecyclePolicy extends AbstractDiffable<SnapshotLifecycleP
return this.repository;
}
@Nullable
public Map<String, Object> getConfig() {
return this.configuration;
}
@ -172,7 +174,7 @@ public class SnapshotLifecyclePolicy extends AbstractDiffable<SnapshotLifecycleP
}
}
if (configuration.containsKey(METADATA_FIELD_NAME)) {
if (configuration != null && configuration.containsKey(METADATA_FIELD_NAME)) {
if (configuration.get(METADATA_FIELD_NAME) instanceof Map == false) {
err.addValidationError("invalid configuration." + METADATA_FIELD_NAME + " [" + configuration.get(METADATA_FIELD_NAME) +
"]: must be an object if present");
@ -265,7 +267,9 @@ public class SnapshotLifecyclePolicy extends AbstractDiffable<SnapshotLifecycleP
builder.field(NAME.getPreferredName(), this.name);
builder.field(SCHEDULE.getPreferredName(), this.schedule);
builder.field(REPOSITORY.getPreferredName(), this.repository);
builder.field(CONFIG.getPreferredName(), this.configuration);
if (this.configuration != null) {
builder.field(CONFIG.getPreferredName(), this.configuration);
}
builder.endObject();
return builder;
}

View File

@ -94,7 +94,7 @@ public class SnapshotHistoryItem implements Writeable, ToXContentObject {
this.snapshotName = Objects.requireNonNull(snapshotName);
this.operation = Objects.requireNonNull(operation);
this.success = success;
this.snapshotConfiguration = Objects.requireNonNull(snapshotConfiguration);
this.snapshotConfiguration = snapshotConfiguration;
this.errorDetails = errorDetails;
}

View File

@ -176,9 +176,12 @@ public class SnapshotHistoryStoreTests extends ESTestCase {
}
public static SnapshotLifecyclePolicy randomSnapshotLifecyclePolicy(String id) {
Map<String, Object> config = new HashMap<>();
for (int i = 0; i < randomIntBetween(2, 5); i++) {
config.put(randomAlphaOfLength(4), randomAlphaOfLength(4));
Map<String, Object> config = null;
if (randomBoolean()) {
config = new HashMap<>();
for (int i = 0; i < randomIntBetween(2, 5); i++) {
config.put(randomAlphaOfLength(4), randomAlphaOfLength(4));
}
}
return new SnapshotLifecyclePolicy(id,
randomAlphaOfLength(4),

View File

@ -131,9 +131,12 @@ public class SnapshotLifecyclePolicyTests extends AbstractSerializingTestCase<Sn
}
public static SnapshotLifecyclePolicy randomSnapshotLifecyclePolicy(String id) {
Map<String, Object> config = new HashMap<>();
for (int i = 0; i < randomIntBetween(2, 5); i++) {
config.put(randomAlphaOfLength(4), randomAlphaOfLength(4));
Map<String, Object> config = null;
if (randomBoolean()) {
config = new HashMap<>();
for (int i = 0; i < randomIntBetween(2, 5); i++) {
config.put(randomAlphaOfLength(4), randomAlphaOfLength(4));
}
}
return new SnapshotLifecyclePolicy(id,
randomAlphaOfLength(4),