Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 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
5 changes: 5 additions & 0 deletions docs/changelog/127252.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pr: 127252
summary: New per-project only settings can be defined and used by components
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't designed to be user-facing, so I wouldn't flag this as a feature for inclusion in release notes.

area: Infra/Settings
type: feature
issues: []
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ static TransportVersion def(int id) {
public static final TransportVersion SYNONYMS_REFRESH_PARAM = def(9_060_0_00);
public static final TransportVersion DOC_FIELDS_AS_LIST = def(9_061_0_00);
public static final TransportVersion DENSE_VECTOR_OFF_HEAP_STATS = def(9_062_00_0);
public static final TransportVersion PROJECT_METADATA_SETTINGS = def(9_063_00_0);

/*
* STOP! READ THIS FIRST! No, really,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,13 @@ private MetadataDiff(StreamInput in) throws IOException {
RESERVED_DIFF_VALUE_READER
);

singleProject = new ProjectMetadata.ProjectMetadataDiff(indices, templates, projectCustoms, DiffableUtils.emptyDiff());
singleProject = new ProjectMetadata.ProjectMetadataDiff(
indices,
templates,
projectCustoms,
DiffableUtils.emptyDiff(),
Settings.EMPTY_DIFF
);
multiProject = null;
} else {
fromNodeBeforeMultiProjectsSupport = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ public class ProjectMetadata implements Iterable<IndexMetadata>, Diffable<Projec
private volatile SortedMap<String, IndexAbstraction> indicesLookup;
private final Map<String, MappingMetadata> mappingsByHash;

private final Settings settings;

private final IndexVersion oldestIndexVersion;

@SuppressWarnings("this-escape")
Expand All @@ -122,6 +124,7 @@ private ProjectMetadata(
String[] visibleClosedIndices,
SortedMap<String, IndexAbstraction> indicesLookup,
Map<String, MappingMetadata> mappingsByHash,
Settings settings,
IndexVersion oldestIndexVersion
) {
this.id = id;
Expand All @@ -140,6 +143,7 @@ private ProjectMetadata(
this.visibleClosedIndices = visibleClosedIndices;
this.indicesLookup = indicesLookup;
this.mappingsByHash = mappingsByHash;
this.settings = settings;
this.oldestIndexVersion = oldestIndexVersion;
assert assertConsistent();
}
Expand Down Expand Up @@ -221,6 +225,7 @@ public ProjectMetadata withLifecycleState(Index index, LifecycleExecutionState l
visibleClosedIndices,
indicesLookup,
mappingsByHash,
settings,
oldestIndexVersion
);
}
Expand Down Expand Up @@ -254,6 +259,7 @@ public ProjectMetadata withIndexSettingsUpdates(Map<Index, Settings> updates) {
visibleClosedIndices,
indicesLookup,
mappingsByHash,
settings,
oldestIndexVersion
);
}
Expand Down Expand Up @@ -288,6 +294,7 @@ public ProjectMetadata withAllocationAndTermUpdatesOnly(Map<String, IndexMetadat
visibleClosedIndices,
indicesLookup,
mappingsByHash,
settings,
oldestIndexVersion
);
}
Expand Down Expand Up @@ -376,6 +383,7 @@ public ProjectMetadata withAddedIndex(IndexMetadata index) {
updatedVisibleClosedIndices,
null,
updatedMappingsByHash,
settings,
IndexVersion.min(index.getCompatibilityVersion(), oldestIndexVersion)
);
}
Expand Down Expand Up @@ -727,6 +735,10 @@ public Map<String, IndexTemplateMetadata> templates() {
return templates;
}

public Settings settings() {
return settings;
}

/**
* Checks whether the provided index is a data stream.
*/
Expand Down Expand Up @@ -1130,6 +1142,7 @@ public static class Builder {
private final ImmutableOpenMap.Builder<String, IndexTemplateMetadata> templates;
private final ImmutableOpenMap.Builder<String, Metadata.ProjectCustom> customs;
private final ImmutableOpenMap.Builder<String, ReservedStateMetadata> reservedStateMetadata;
private Settings settings = Settings.EMPTY;

private SortedMap<String, IndexAbstraction> previousIndicesLookup;

Expand All @@ -1147,6 +1160,7 @@ public static class Builder {
this.templates = ImmutableOpenMap.builder(projectMetadata.templates);
this.customs = ImmutableOpenMap.builder(projectMetadata.customs);
this.reservedStateMetadata = ImmutableOpenMap.builder(projectMetadata.reservedStateMetadata);
this.settings = projectMetadata.settings;
this.previousIndicesLookup = projectMetadata.indicesLookup;
this.mappingsByHash = new HashMap<>(projectMetadata.mappingsByHash);
this.checkForUnusedMappings = false;
Expand Down Expand Up @@ -1525,6 +1539,15 @@ public Builder removeReservedState(ReservedStateMetadata metadata) {
return this;
}

public Settings settings() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having accessor methods on Builder seems kinda odd to me. We had to have passed this in already, so why not just hold a reference to what we pass to settings() instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: #127280

return this.settings;
}

public ProjectMetadata.Builder settings(Settings settings) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no need to qualify this here. We can just use Builder as the type was we do elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: #127280

this.settings = settings;
return this;
}

public Builder indexGraveyard(final IndexGraveyard indexGraveyard) {
return putCustom(IndexGraveyard.TYPE, indexGraveyard);
}
Expand Down Expand Up @@ -1684,6 +1707,7 @@ public ProjectMetadata build(boolean skipNameCollisionChecks) {
visibleClosedIndicesArray,
indicesLookup,
Collections.unmodifiableMap(mappingsByHash),
settings,
IndexVersion.fromId(oldestIndexVersionId)
);
}
Expand Down Expand Up @@ -2110,6 +2134,9 @@ public static ProjectMetadata fromXContent(XContentParser parser) throws IOExcep
projectBuilder.put(IndexTemplateMetadata.Builder.fromXContent(parser, parser.currentName()));
}
}
case "settings" -> {
projectBuilder.settings(Settings.fromXContent(parser));
}
default -> Metadata.Builder.parseCustomObject(
parser,
currentFieldName,
Expand Down Expand Up @@ -2157,7 +2184,8 @@ public Iterator<? extends ToXContent> toXContentChunked(ToXContent.Params p) {
customs,
multiProject
? ChunkedToXContentHelper.object("reserved_state", reservedStateMetadata().values().iterator())
: Collections.emptyIterator()
: Collections.emptyIterator(),
multiProject ? ChunkedToXContentHelper.object("settings", Iterators.single(settings)) : Collections.emptyIterator()
);
}

Expand Down Expand Up @@ -2189,6 +2217,10 @@ public static ProjectMetadata readFrom(StreamInput in) throws IOException {
builder.put(ReservedStateMetadata.readFrom(in));
}

if (in.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
builder.settings(Settings.readSettingsFromStream(in));
}

return builder.build();
}

Expand Down Expand Up @@ -2229,6 +2261,10 @@ public void writeTo(StreamOutput out) throws IOException {
}
VersionedNamedWriteable.writeVersionedWriteables(out, filteredCustoms);
out.writeCollection(reservedStateMetadata.values());

if (out.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
settings.writeTo(out);
}
}

// this needs to be package accessible for bwc serialization in Metadata.java
Expand All @@ -2248,13 +2284,15 @@ static class ProjectMetadataDiff implements Diff<ProjectMetadata> {
String,
ReservedStateMetadata,
ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata;
private final Diff<Settings> settingsDiff;

private ProjectMetadataDiff(ProjectMetadata before, ProjectMetadata after) {
if (before == after) {
indices = DiffableUtils.emptyDiff();
templates = DiffableUtils.emptyDiff();
customs = DiffableUtils.emptyDiff();
reservedStateMetadata = DiffableUtils.emptyDiff();
settingsDiff = Settings.EMPTY_DIFF;
} else {
indices = DiffableUtils.diff(before.indices, after.indices, DiffableUtils.getStringKeySerializer());
templates = DiffableUtils.diff(before.templates, after.templates, DiffableUtils.getStringKeySerializer());
Expand All @@ -2269,19 +2307,22 @@ private ProjectMetadataDiff(ProjectMetadata before, ProjectMetadata after) {
after.reservedStateMetadata,
DiffableUtils.getStringKeySerializer()
);
settingsDiff = after.settings.diff(before.settings);
}
}

ProjectMetadataDiff(
DiffableUtils.MapDiff<String, IndexMetadata, ImmutableOpenMap<String, IndexMetadata>> indices,
DiffableUtils.MapDiff<String, IndexTemplateMetadata, ImmutableOpenMap<String, IndexTemplateMetadata>> templates,
DiffableUtils.MapDiff<String, Metadata.ProjectCustom, ImmutableOpenMap<String, Metadata.ProjectCustom>> customs,
DiffableUtils.MapDiff<String, ReservedStateMetadata, ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata
DiffableUtils.MapDiff<String, ReservedStateMetadata, ImmutableOpenMap<String, ReservedStateMetadata>> reservedStateMetadata,
Diff<Settings> settingsDiff
) {
this.indices = indices;
this.templates = templates;
this.customs = customs;
this.reservedStateMetadata = reservedStateMetadata;
this.settingsDiff = settingsDiff;
}

ProjectMetadataDiff(StreamInput in) throws IOException {
Expand All @@ -2293,6 +2334,11 @@ private ProjectMetadataDiff(ProjectMetadata before, ProjectMetadata after) {
DiffableUtils.getStringKeySerializer(),
RESERVED_DIFF_VALUE_READER
);
if (in.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
settingsDiff = Settings.readSettingsDiffFromStream(in);
} else {
settingsDiff = Settings.EMPTY_DIFF;
}
}

Diff<ImmutableOpenMap<String, IndexMetadata>> indices() {
Expand All @@ -2317,11 +2363,18 @@ public void writeTo(StreamOutput out) throws IOException {
templates.writeTo(out);
customs.writeTo(out);
reservedStateMetadata.writeTo(out);
if (out.getTransportVersion().onOrAfter(TransportVersions.PROJECT_METADATA_SETTINGS)) {
settingsDiff.writeTo(out);
}
}

@Override
public ProjectMetadata apply(ProjectMetadata part) {
if (indices.isEmpty() && templates.isEmpty() && customs.isEmpty() && reservedStateMetadata.isEmpty()) {
if (indices.isEmpty()
&& templates.isEmpty()
&& customs.isEmpty()
&& reservedStateMetadata.isEmpty()
&& settingsDiff == Settings.EMPTY_DIFF) {
// nothing to do
return part;
}
Expand All @@ -2336,13 +2389,14 @@ public ProjectMetadata apply(ProjectMetadata part) {
&& builder.dataStreamMetadata() == part.custom(DataStreamMetadata.TYPE, DataStreamMetadata.EMPTY)) {
builder.previousIndicesLookup = part.indicesLookup;
}
builder.settings = settingsDiff.apply(builder.settings);
return builder.build(true);
}

ProjectMetadataDiff withCustoms(
DiffableUtils.MapDiff<String, Metadata.ProjectCustom, ImmutableOpenMap<String, Metadata.ProjectCustom>> customs
) {
return new ProjectMetadataDiff(indices, templates, customs, reservedStateMetadata);
return new ProjectMetadataDiff(indices, templates, customs, reservedStateMetadata, settingsDiff);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.elasticsearch.common.Priority;
import org.elasticsearch.common.component.AbstractLifecycleComponent;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.ProjectScopedSettings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
Expand All @@ -31,6 +32,8 @@
import org.elasticsearch.tasks.TaskManager;
import org.elasticsearch.threadpool.ThreadPool;

import java.util.Collections;

public class ClusterService extends AbstractLifecycleComponent {
private final MasterService masterService;

Expand All @@ -52,12 +55,31 @@ public class ClusterService extends AbstractLifecycleComponent {

private final ClusterSettings clusterSettings;

private final ProjectScopedSettings projectScopedSettings;

private final String nodeName;

public ClusterService(Settings settings, ClusterSettings clusterSettings, ThreadPool threadPool, TaskManager taskManager) {
this(
settings,
clusterSettings,
new ProjectScopedSettings(settings, Collections.emptySet()),
new MasterService(settings, clusterSettings, threadPool, taskManager),
new ClusterApplierService(Node.NODE_NAME_SETTING.get(settings), settings, clusterSettings, threadPool)
);
}

public ClusterService(
Settings settings,
ClusterSettings clusterSettings,
ProjectScopedSettings projectScopedSettings,
ThreadPool threadPool,
TaskManager taskManager
) {
this(
settings,
clusterSettings,
projectScopedSettings,
new MasterService(settings, clusterSettings, threadPool, taskManager),
new ClusterApplierService(Node.NODE_NAME_SETTING.get(settings), settings, clusterSettings, threadPool)
);
Expand All @@ -68,10 +90,21 @@ public ClusterService(
ClusterSettings clusterSettings,
MasterService masterService,
ClusterApplierService clusterApplierService
) {
this(settings, clusterSettings, new ProjectScopedSettings(settings, Collections.emptySet()), masterService, clusterApplierService);
}

public ClusterService(
Settings settings,
ClusterSettings clusterSettings,
ProjectScopedSettings projectScopedSettings,
MasterService masterService,
ClusterApplierService clusterApplierService
) {
this.settings = settings;
this.nodeName = Node.NODE_NAME_SETTING.get(settings);
this.masterService = masterService;
this.projectScopedSettings = projectScopedSettings;
this.operationRouting = new OperationRouting(settings, clusterSettings);
this.clusterSettings = clusterSettings;
this.clusterName = ClusterName.CLUSTER_NAME_SETTING.get(settings);
Expand Down Expand Up @@ -201,6 +234,10 @@ public ClusterSettings getClusterSettings() {
return clusterSettings;
}

public ProjectScopedSettings getProjectScopedSettings() {
return projectScopedSettings;
}

/**
* The node's settings.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the "Elastic License
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
* Public License v 1"; you may not use this file except in compliance with, at
* your election, the "Elastic License 2.0", the "GNU Affero General Public
* License v3.0 only", or the "Server Side Public License, v 1".
*/

package org.elasticsearch.common.settings;

import java.util.Set;

public class ProjectScopedSettings extends AbstractScopedSettings {
public ProjectScopedSettings(Settings settings, Set<Setting<?>> settingsSet) {
super(settings, settingsSet, Setting.Property.ProjectScope);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,12 @@ public enum Property {
* All other settings will be rejected when used on a PUT request
* and filtered out on a GET
*/
ServerlessPublic
ServerlessPublic,

/**
* Project-level file-level setting. Not an index setting.
*/
ProjectScope
}

private final Key key;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
public final class Settings implements ToXContentFragment, Writeable, Diffable<Settings> {

public static final Settings EMPTY = new Settings(Map.of(), null);
public static final Diff<Settings> EMPTY_DIFF = new SettingsDiff(DiffableUtils.emptyDiff());

public static final String FLAT_SETTINGS_PARAM = "flat_settings";

Expand Down
Loading
Loading