Migrate high-level serialization to System.Text.Json - #1002
Open
YiyuanMiao wants to merge 92 commits into
Open
Conversation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Migrate high-level serialization to System.Text.Json
Related to #388.
Migrates the
OpenSearch.Clienthigh-level serializer (and the low-levelOpenSearch.Netserializer) from the bundled, unmaintained Utf8Json fork to System.Text.Json (STJ), and makes STJ the default engine. The legacy Utf8Json engine is kept as a fully supported opt-out fallback.Why
Utf8Json is deprecated and unmaintained.
System.Text.Jsonis the official, supported, actively-maintained .NET JSON stack. This removes the reliance on the bundled fork for the default serialization path while preserving backward compatibility through an opt-out.What changed
SystemTextJsonSerializerand a high-levelSystemTextJsonHighLevelSerializerdriven by a settings-awareIJsonTypeInfoResolver(HighLevelContractResolver/InterfaceDataContractResolver) that reproduces the legacy engine's runtime-config-driven behaviour (field-name inference, per-member property mappings,[DataMember]/[InterfaceDataContract],ShouldSerializeconventions, explicit-interface andnon-public members).
IJsonFormatter<T>toJsonConverter<T>, across simple values, dates/times (ISO 8601 + epoch/ticks), collections and dictionaries, inference types, unions, geo, analysis, queries (field-name, fuzzy, terms, range, geo, span), aggregations, properties/mappings, proxy requests, and responses. Open generics are wired viaJsonConverterFactory.double/float/decimalkeep the legacy trailing.0;[StringEnum]values serialize with the verbatim field name; member- and type-levelShouldSerializeare honoured(empty bool queries and empty routing are omitted);
[PropertyName]/ OSC mapping-attribute / property-mapping-provider naming precedence; object-keyed and read-only dictionaries;ValueTuple; single-or-array coercions; document bodies (index/create/bulk/terms) delegate to the configuredSourceSerializer;Error/ServerErrordeserialization.ConnectionSettingsnow defaults to STJ. SetOSC_USE_UTF8JSON=true(orOSC_USE_STJ=false) to fall back to the legacy Utf8Json engine.OSC_USE_UTF8JSON=true) via a serializer matrix, so neither path can silently regress.The bundled Utf8Json library is intentionally retained — it is the implementation behind the
OSC_USE_UTF8JSONfallback, which is a permanently supported escape hatch.Compatibility
ConnectionSettings(..., sourceSerializer: ...)(e.g. theOpenSearch.Client.JsonNetSerializerpackage) is unaffected under either engine.Testing
Unit tests: the full suite passes on both engines. Both produce the same small set of pre-existing failures that are unrelated to serialization (naming-convention code standards, a role-detection sniffing test, and the JSON.NET low-level exception-parity test) — i.e. STJ is at parity with Utf8Json.
Real-cluster integration (manual): index / get / search (match + term on
.keyword) / bulk / update / average aggregation / delete-by-query round-trips against a 4-node OpenSearch cluster passed 16/16 on STJ and 16/16 on Utf8Json. (OpenSearch publishes no macOS distribution, so the repo's ephemeral integration harness cannot run natively on macOS; this was validated against a Docker cluster instead.)Benchmarks (BenchmarkDotNet, .NET 10, arm64): STJ is ~1.2–1.4× slower than Utf8Json with slightly higher allocations — expected, since Utf8Json was a hand-tuned library; absolute costs are microsecond-scale and dominated by network/cluster time in practice. Performance-sensitive callers can opt into the Utf8Json fallback.
Check list
--signoff