Skip to content

fix: remove RuleQueryMatchCriteria hacks and prefer env vars over secrets#3462

Merged
Mpdreamz merged 1 commit into
mainfrom
fix/search-contract
Jun 3, 2026
Merged

fix: remove RuleQueryMatchCriteria hacks and prefer env vars over secrets#3462
Mpdreamz merged 1 commit into
mainfrom
fix/search-contract

Conversation

@Mpdreamz
Copy link
Copy Markdown
Member

@Mpdreamz Mpdreamz commented Jun 3, 2026

Summary

  • Bump Elastic.Internal.Search.{Contract,Elasticsearch} to 0.9.2 which properly exposes RuleQueryMatchCriteria with a source-gen context for AOT serialization
  • Remove the reflection-based RuleQueryMatchCriteriaTypeInfoResolver and RuleQueryMatchCriteriaJsonConverterFactory that broke under .NET 10's stricter JsonSerializerOptions compatibility checks
  • Reorder config lookups in ElasticsearchEndpointFactory so environment variables take precedence over dotnet user secrets, making it easier to override endpoints in CI/containers
  • Suppress noisy OpenTelemetry logs (default to Warning) in MCP server appsettings

Context

The old workarounds for serializing the internal RuleQueryMatchCriteria type used DynamicDependency, UnsafeAccessor, and cached JsonTypeInfo — these broke in .NET 10 with:

The IJsonTypeInfoResolver returned a JsonTypeInfo instance whose JsonSerializerOptions setting does not match the provided argument.

The proper fix (elastic/website-search-data#198) makes the type public and adds a SourceGenerationContext in the Elastic.Internal.Search.Elasticsearch package. This PR consumes that fix by chaining the new context into the resolver.

Test plan

  • dotnet build passes for Elastic.Documentation.Search, MCP server, and integration tests
  • Search integration tests pass against production Elasticsearch
  • MCP server starts and serves tool calls without serialization errors

Made with Cursor

…rets

- Bump Elastic.Internal.Search.{Contract,Elasticsearch} to 0.9.2 which
  exposes RuleQueryMatchCriteria and its SourceGenerationContext for
  AOT-compatible serialization
- Remove the reflection-based RuleQueryMatchCriteriaTypeInfoResolver and
  RuleQueryMatchCriteriaJsonConverterFactory that broke under .NET 10's
  stricter JsonSerializerOptions compatibility checks
- Chain the new Elasticsearch package SourceGenerationContext into the
  resolver so rule queries serialize correctly without reflection
- Reorder config lookups in ElasticsearchEndpointFactory so environment
  variables take precedence over dotnet user secrets
- Suppress noisy OpenTelemetry logs (default to Warning) in MCP server
  appsettings

Co-authored-by: Cursor <cursoragent@cursor.com>
@Mpdreamz Mpdreamz requested a review from a team as a code owner June 3, 2026 08:55
@Mpdreamz Mpdreamz requested a review from reakaleek June 3, 2026 08:55
@Mpdreamz Mpdreamz temporarily deployed to integration-tests June 3, 2026 08:55 — with GitHub Actions Inactive
@Mpdreamz Mpdreamz added the fix label Jun 3, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 3, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR upgrades Elasticsearch internal search packages to 0.9.2, refactors the configuration system to favor environment variables over user secrets, and removes custom JSON serialization logic in favor of source generation contexts. It adds OpenTelemetry logging configuration across environments and updates integration tests to remove hardcoded environment parameters, allowing them to use the new configuration priority system.

Possibly related PRs

  • elastic/docs-builder#3433: Prior PR that introduced the RuleQueryMatchCriteria JSON converter and type-info resolver wiring that this PR removes in favor of source generation.
  • elastic/docs-builder#3455: Also updates Directory.Packages.props with bumps to the same Elastic.Internal.Search packages.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title concisely and accurately summarizes the two main changes: removing workarounds for RuleQueryMatchCriteria and reordering config to prefer environment variables over secrets.
Description check ✅ Passed The description is well-organized and directly related to the changeset, explaining the motivation, changes made, and test coverage for all modifications in the PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/search-contract

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/Elastic.Documentation.ServiceDefaults/ElasticsearchEndpointFactory.cs (1)

83-92: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Map standard host environment names before the allowlist.

DOTNET_ENVIRONMENT is typically Development, Staging, or Production. The new check only accepts dev|prod|staging before normalization, so Production and Staging now collapse to "dev". That makes callers that stopped passing environment: "dev" resolve the wrong index/endpoint outside local dev.

Suggested fix
-		string[] allowedEnvironements = ["dev", "prod", "staging"];
-		if (!allowedEnvironements.Contains(envVar))
-			envVar = "dev";
-
-		return !string.IsNullOrEmpty(envVar) ? envVar.ToLowerInvariant() : "dev";
+		return envVar?.Trim().ToLowerInvariant() switch
+		{
+			"development" or "dev" => "dev",
+			"staging" => "staging",
+			"production" or "prod" => "prod",
+			_ => "dev"
+		};
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/Elastic.Documentation.ServiceDefaults/ElasticsearchEndpointFactory.cs`
around lines 83 - 92, The envVar lookup in ElasticsearchEndpointFactory.cs
currently compares raw values against allowedEnvironements and defaults to
"dev", which causes canonical values like "Production" or "Development" to be
treated as invalid; update the logic so you first normalize envVar (e.g., call
ToLowerInvariant and Trim) and map standard .NET environment names
("development" -> "dev", "production" -> "prod", "staging" -> "staging") before
checking the allowlist (allowedEnvironments) — then validate against the
allowlist and return the normalized mapped value (or "dev" as fallback); ensure
you update the variable names if needed (envVar, allowedEnvironments) and
preserve the final return semantics.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/Elastic.Documentation.ServiceDefaults/ElasticsearchEndpointFactory.cs`:
- Around line 83-92: The envVar lookup in ElasticsearchEndpointFactory.cs
currently compares raw values against allowedEnvironements and defaults to
"dev", which causes canonical values like "Production" or "Development" to be
treated as invalid; update the logic so you first normalize envVar (e.g., call
ToLowerInvariant and Trim) and map standard .NET environment names
("development" -> "dev", "production" -> "prod", "staging" -> "staging") before
checking the allowlist (allowedEnvironments) — then validate against the
allowlist and return the normalized mapped value (or "dev" as fallback); ensure
you update the variable names if needed (envVar, allowedEnvironments) and
preserve the final return semantics.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 8951534c-2dcb-47b9-b291-d8e50ce72b63

📥 Commits

Reviewing files that changed from the base of the PR and between c10789a and f3c28d5.

📒 Files selected for processing (11)
  • Directory.Packages.props
  • src/Elastic.Documentation.ServiceDefaults/ElasticsearchEndpointFactory.cs
  • src/api/Elastic.Documentation.Mcp.Remote/appsettings.development.json
  • src/api/Elastic.Documentation.Mcp.Remote/appsettings.edge.json
  • src/api/Elastic.Documentation.Mcp.Remote/appsettings.json
  • src/services/search/Elastic.Documentation.Search/Common/ElasticsearchClientAccessor.cs
  • src/services/search/Elastic.Documentation.Search/Common/ElasticsearchClientJsonResolver.cs
  • src/services/search/Elastic.Documentation.Search/Common/RuleQueryMatchCriteriaJsonConverter.cs
  • src/services/search/Elastic.Documentation.Search/Common/RuleQueryMatchCriteriaTypeInfoResolver.cs
  • tests-integration/Mcp.Remote.IntegrationTests/McpToolsIntegrationTestsBase.cs
  • tests-integration/Search.IntegrationTests/SearchRelevanceTests.cs
💤 Files with no reviewable changes (2)
  • src/services/search/Elastic.Documentation.Search/Common/RuleQueryMatchCriteriaTypeInfoResolver.cs
  • src/services/search/Elastic.Documentation.Search/Common/RuleQueryMatchCriteriaJsonConverter.cs

@Mpdreamz Mpdreamz merged commit 576e12b into main Jun 3, 2026
25 of 26 checks passed
@Mpdreamz Mpdreamz deleted the fix/search-contract branch June 3, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant