Allow affix settings to specify dependencies#27161
Conversation
We use affix settings to group settings / values under a certain namespace. In some cases like login information for instance a setting is only valid if one or more other settings are present. For instance `x.test.user` is only valid if there is an `x.test.passwd` present and vice versa. This change allows to specify such a dependency to prevent settings updates that leave settings in an inconsistent state.
|
/cc @javanna |
|
@s1monw I have been trying this out in #27182. Do I understand correctly that a setting which is dependent on another setting must always be provided in the same request as its dependency? That makes sense for user and password, but in CCS one may want to change the You can reproduce with the following unit test: |
|
@javanna I applied your feedback thx |
c700c5e to
278f416
Compare
|
@elasticmachine test this please |
|
@javanna can you take another look? |
javanna
left a comment
There was a problem hiding this comment.
I tested it out and it works well with the changes from #27182 . I left a few minor comments and a couple of questions. The only minor thing that I wish we could improve, but I am not sure we can, is the error message when you set to null a setting that another one left behind depends on. It may not be clear to users what they have to do to fix that (e.g. set to null the other setting too).
| public static final Setting<String> PROXY_HOST_SETTING = Setting.affixKeySetting(PREFIX, "proxy.host", | ||
| (key) -> Setting.simpleString(key, Property.NodeScope)); | ||
| public static final Setting<String> PROXY_HOST_SETTING = Setting.affixKeySetting("azure.client.", "proxy.host", | ||
| (key) -> Setting.simpleString(key, Property.NodeScope), KEY_SETTING, ACCOUNT_SETTING, KEY_SETTING); |
There was a problem hiding this comment.
I guess KEY_SETTING shouldn't be repeated twice?
| public static final Setting<Integer> PROXY_PORT_SETTING = Setting.affixKeySetting(PREFIX, "proxy.port", | ||
| (key) -> Setting.intSetting(key, 0, 0, 65535, Setting.Property.NodeScope)); | ||
| public static final Setting<Integer> PROXY_PORT_SETTING = Setting.affixKeySetting("azure.client.", "proxy.port", | ||
| (key) -> Setting.intSetting(key, 0, 0, 65535, Setting.Property.NodeScope), ACCOUNT_SETTING, KEY_SETTING); |
There was a problem hiding this comment.
wondering, shouldn't it also depend on proxy_host ?
| (key) -> new Setting<>(key, "direct", s -> Proxy.Type.valueOf(s.toUpperCase(Locale.ROOT)), Property.NodeScope)); | ||
| public static final AffixSetting<Proxy.Type> PROXY_TYPE_SETTING = Setting.affixKeySetting("azure.client.", "proxy.type", | ||
| (key) -> new Setting<>(key, "direct", s -> Proxy.Type.valueOf(s.toUpperCase(Locale.ROOT)), Property.NodeScope) | ||
| , ACCOUNT_SETTING, KEY_SETTING); |
There was a problem hiding this comment.
not too familiar with these settings, does proxy_type depend also on proxy_host and proxy_port?
There was a problem hiding this comment.
yeah I am not sure about that
|
|
||
| } | ||
|
|
||
|
|
There was a problem hiding this comment.
nit: remove this additional empty line
| /** | ||
| * Returns distinct namespaces for the given settings | ||
| */ | ||
| public Set<String> getNamespaces(Settings settings) { |
There was a problem hiding this comment.
nit: match(key) could be replaced with a method reference this::match
| } | ||
| metaDataBuilder.put(IndexMetaData.builder(indexMetaData).settings(indexSettings)); | ||
| Settings finalSettings = indexSettings.build(); | ||
| indexScopedSettings.validate(finalSettings.filter(k -> indexScopedSettings.isPrivateSetting(k) == false), true); |
There was a problem hiding this comment.
question: private settings are internal only, hence we want to get them out of the validation?
| if (changed) { | ||
| Settings transientFinalSettings = transientSettings.build(); | ||
| Settings persistentFinalSettings = persistentSettings.build(); | ||
| // both transient and persistent settings must be consistent by itself we can't allow dependencies to be |
There was a problem hiding this comment.
"must be consistent on their own?"
There was a problem hiding this comment.
"we can't allow dependencies between the two"?
There was a problem hiding this comment.
what if you have setting A to be transient and then it disappears on a full cluster restart?
There was a problem hiding this comment.
sure I agree, I was just suggesting to rephrase the comment :)
|
|
||
| try { | ||
| indexScopedSettings.validate(request.settings); | ||
| indexScopedSettings.validate(request.settings, true); // templates must be consistent with regards to dependecies |
| metaDataBuilder.put(IndexMetaData.builder(indexMetaData).settings(indexSettings)); | ||
| Settings finalSettings = indexSettings.build(); | ||
| indexScopedSettings.validate(finalSettings.filter(k -> indexScopedSettings.isPrivateSetting(k) == false), true); | ||
| metaDataBuilder.put(IndexMetaData.builder(indexMetaData).settings(finalSettings)); |
There was a problem hiding this comment.
I was wondering if this second step wasn't enough, compared to the first validation step that doesn't look at dependencies. Why have the two steps?
There was a problem hiding this comment.
one happens before we pass on to a clusterstate update task we should validate as soon as we can. but we have to do it here again
jasontedor
left a comment
There was a problem hiding this comment.
This looks good to me, I left one minor request.
| final Settings.Builder templateSettingsBuilder = Settings.builder(); | ||
| templateSettingsBuilder.put(request.settings()).normalizePrefix(IndexMetaData.INDEX_SETTING_PREFIX); | ||
| indexScopedSettings.validate(templateSettingsBuilder); | ||
| indexScopedSettings.validate(templateSettingsBuilder.build(), true); // templates must be consistent with reg. to dependencies |
There was a problem hiding this comment.
Can you expand reg.? It took me a few seconds to figure out what it meant (regards) and I do not want to have to do it every time I read this comment?
|
|
||
| public final class AzureStorageSettings { | ||
| // prefix for azure client settings | ||
| private static final String PREFIX = "azure.client."; |
There was a problem hiding this comment.
Why remove the internal constant? Seems like this is just asking for a typo in the future in one setting to cause a storm of problems :/
There was a problem hiding this comment.
fair enough. I can add it back.
We use affix settings to group settings / values under a certain namespace. In some cases like login information for instance a setting is only valid if one or more other settings are present. For instance `x.test.user` is only valid if there is an `x.test.passwd` present and vice versa. This change allows to specify such a dependency to prevent settings updates that leave settings in an inconsistent state.
* es/master: (24 commits) Reduce synchronization on field data cache add json-processor support for non-map json types (#27335) Properly format IndexGraveyard deletion date as date (#27362) Upgrade AWS SDK Jackson Databind to 2.6.7.1 Stop responding to ping requests before master abdication (#27329) [Test] Fix POI version in packaging tests Allow affix settings to specify dependencies (#27161) Tests: Improve size regex in documentation test (#26879) reword comment Remove unnecessary logger creation for doc values field data [Geo] Decouple geojson parse logic from ShapeBuilders [DOCS] Fixed link to docker content Plugins: Add versionless alias to all security policy codebase properties (#26756) [Test] #27342 Fix SearchRequests#testValidate [DOCS] Move X-Pack-specific Docker content (#27333) Fail queries with scroll that explicitely set request_cache (#27342) [Test] Fix S3BlobStoreContainerTests.testNumberOfMultiparts() Set minimum_master_nodes to all nodes for REST tests (#27344) [Tests] Relax allowed delta in extended_stats aggregation (#27171) Remove S3 output stream (#27280) ...
* 6.x: (27 commits) Reduce synchronization on field data cache [Test] #27342 Fix SearchRequests#testValidate Fail queries with scroll that explicitely set request_cache (#27342) add json-processor support for non-map json types (#27335) Upgrade AWS SDK Jackson Databind to 2.6.7.1 Properly format IndexGraveyard deletion date as date (#27362) Stop responding to ping requests before master abdication (#27329) [Test] Fix POI version in packaging tests Added release notes for 6.0.0 Update 6.0.0-beta1.asciidoc Allow affix settings to specify dependencies (#27161) Tests: Improve size regex in documentation test (#26879) reword comment Ensure external refreshes will also refresh internal searcher to minimize segment creation (#27253) Remove unnecessary logger creation for doc values field data [DOCS] Fixed link to docker content Plugins: Add versionless alias to all security policy codebase properties (#26756) [DOCS] Move X-Pack-specific Docker content (#27333) [Test] Fix S3BlobStoreContainerTests.testNumberOfMultiparts() Set minimum_master_nodes to all nodes for REST tests (#27344) ...
We use affix settings to group settings / values under a certain namespace.
In some cases like login information for instance a setting is only valid if
one or more other settings are present. For instance
x.test.useris only validif there is an
x.test.passwdpresent and vice versa. This change allows to specifysuch a dependency to prevent settings updates that leave settings in an inconsistent
state.