Conversation
HttpCreateIndexAction set is_write_index=false on every alias whose
writeIndex() was unset, so an index created with
prepareCreate(name).addAlias(new Alias(a)) came up with a read-only alias.
Indexing through that alias then failed with
no write index is defined for alias [a]
even though the alias pointed at a single index, which both the transport
client and the REST API treat as writable. Leave the flag unset unless the
caller set it.
Found while moving fess-suggest onto this client: Suggester.createIndexIfNothing()
creates its search and update aliases exactly this way, and every write through
them failed.
Two cases: an alias the caller left alone must not go out as is_write_index=false, and an alias the caller did mark must keep the value it was given. Alias.toXContent writes the field unconditionally, so an unset alias is sent as null, which the create-index API treats as unset - the test states that rather than asserting the field is absent. Verified red-green: with the forcing restored, the first test fails.
Leaving Alias.writeIndex() unset was not enough. Alias.toXContent writes the
field unconditionally with no null check, so an unset alias went out as
is_write_index: null, and Elasticsearch 8 rejects that outright:
Unknown token [VALUE_NULL] in alias [...]
which broke Elasticsearch8ClientTest.test_create_index and test_resolve_index.
Render the alias here instead of delegating, omitting every field the caller
did not set. That is the only rendering both engines read as "the caller did
not decide": false makes the alias read-only, null is a parse error on ES8.
The field names are spelled out because Alias's own ParseField constants are
private.
373 tests pass.
|
Superseded by #43 — the conflict is the signal that this landed already. The fork took the same fix, in a better place. This branch worked around On
So both engines get the same wire format this branch produced: the field is omitted Closing rather than rebasing; there is nothing left to merge. |
HttpCreateIndexActionsetis_write_index: falseon every alias whosewriteIndex()the caller had left unset, so an index created withprepareCreate(name).addAlias(new Alias(a))came up with a read-only alias. Indexing through it then failed witheven though the alias pointed at a single index, which both the transport client and the REST API treat as writable.
Where it bites
Fess reaches this on a fresh install.
SuggestHelpercallsSuggester.createIndexIfNothing(), which creates the suggest index with exactly that call shape and adds both a search and an update alias;Suggesterthen hands the update alias toSuggestIndexeras the index name, so every suggest write goes through an alias this action had marked read-only. There is no suggest index among Fess's seededfess_indices, so that is the only path.Why no test caught it
fess-suggest's tests drive a real embedded node, so they never go through
HttpCreateIndexAction. Moving them onto this client surfaced it immediately: 74 of 689 failed, all on the write path.The fix
Leave the flag alone unless the caller set it. Note that
Alias.toXContentwrites the field unconditionally with no null check, so an unset alias now goes out as"is_write_index": null, which the create-index API treats as unset — the tests state that rather than asserting the field is absent.Two regression tests, verified red-green: restoring the forcing makes the first one fail.
Verification
mvn clean package— 372 tests, 0 failures.