Skip to content

Cherry-pick for release/2.0: REST/OpenAPI/CLI/config-validation bug fixes#3516

Open
aaronburtle wants to merge 9 commits intorelease/2.0from
dev/aaronburtle/Cherry-Pick-2.0
Open

Cherry-pick for release/2.0: REST/OpenAPI/CLI/config-validation bug fixes#3516
aaronburtle wants to merge 9 commits intorelease/2.0from
dev/aaronburtle/Cherry-Pick-2.0

Conversation

@aaronburtle
Copy link
Copy Markdown
Contributor

Why make this change?

Closes #3515

Ports a set of REST, OpenAPI, CLI, and configuration-validation bug fixes from main to release/2.0 so the 2.0 release line includes:

  • Correct HTTP semantics for invalid If-Match headers on REST PUT/PATCH (now returns 400 instead of mishandling).
  • Cleaner OpenAPI documents — descriptive 404 message when filtering by a missing role, and removal of redundant _NoAutoPK / _NoPK schemas when request-body-strict is false.
  • Accurate config validation: corrected JSON-type mapping for int system types, alignment of parent/child config behavior during deserialization and startup, and improved entity validation logic.
  • Schema completeness: level-2 property on runtime.cache in dab.draft.schema.json.
  • CLI quality-of-life: consistent log labels matching ASP.NET Core's default console formatter, and clearer error messaging from dab validate when a logger is not yet available.

What is this change?

Cherry-picked PRs (chronological order on main):

How was this tested?

Existing and newly added unit/integration tests from each source PR.

aaronburtle and others added 9 commits May 5, 2026 23:24
## Why make this change?

Closes #3314

## What is this change?

Adds the `level-2` property, which is already a part of our object
model, to the `dab.draft.schema.json` file. Also adds `minimum: 1` to
`runtime.cache.ttl-seconds` to align schema validation with the runtime
enforcement that rejects values ≤ 0. The `level-2.provider` property is
kept as a plain string (no enum, no default) to match the nullable
string with `null` default in the object model.

## How was this tested?

- [ ] Integration Tests
- [ ] Unit Tests

## Sample Request(s)

N/A — schema-only change with no REST/GraphQL/CLI surface.

<!-- START COPILOT CODING AGENT TIPS -->
---

📍 Connect Copilot coding agent with [Jira](https://gh.io/cca-jira-docs),
[Azure Boards](https://gh.io/cca-azure-boards-docs) or
[Linear](https://gh.io/cca-linear-docs) to delegate work to Copilot in
one click without leaving your project management tool.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
(cherry picked from commit b301eeb)
…label on startup (#3307)

## Why make this change?

Closes #3269

## What is this change?

Align the CLI logger labels with the labels used in ASP.Net Core.
Downgraded internal plumbing message from `Information` to `Debug`

Add a test case to cover the changed behavior.

## How was this tested?

Added a test case to validate the new behavior.

(cherry picked from commit 75b8eec)
…n and startup (#3321)

## Why make this change?

Closes #3271

## What is this change?

Previously, child configs were defaulting to `throw` for their exception
behavior during deserialization, but parent configs correctly use
`ignore`. We align this behavior. Furthermore, during startup of the
engine we throw an exception if a child config itself can not be loaded,
halting startup, as would happen with the parent.

When a child config file exists but fails to load, a generic diagnostic
message is surfaced: `"Failed to load datasource file: {path}. Ensure
the file is accessible and contains a valid DAB configuration."` —
covering all failure modes including invalid JSON, IO errors, and
permission issues.

## How was this tested?

Added 2 new tests:
1. `ChildConfigWithMissingEnvVarsLoadsSuccessfully` — verifies that a
child config with unresolved `@env()` references loads successfully (env
vars saved and restored in `finally`; uses unique temp file path)
2. `ChildConfigLoadFailureHaltsParentConfigLoading` — verifies that a
child config file that exists but contains invalid JSON causes parent
config loading to fail (saves/restores `Console.Error` and disposes
`StringWriter` in `finally`; uses unique temp file path)

Updated `TestLoadRuntimeConfigSubFilesFails` to assert that non-existent
child config files are gracefully skipped (not treated as failures).

- [x] Unit Tests

---------

Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
(cherry picked from commit c014e52)
## Why make this change?

Closes #3261

## What is this change?

In the `RestController`, add descriptive messaging for `NotFound()` when
role is missing. Add a test case to cover this new behavior.

## How was this tested?

Test case added.

Manually verified the endpoint provided the correct response.

<img width="566" height="193" alt="image"
src="https://github.com/user-attachments/assets/e0549b70-b605-4ddc-a5d4-a107a91361ea"
/>

## Sample Request(s)

Can manually verify by going to this endpoint without a "foo" role
defined.

`https://localhost:5001/rest/openapi/foo`

---------

Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
(cherry picked from commit 5fa2bfc)
## Why make this change?

Closes #3397

## What is this change?

When `DeterminePatchPutSemantics` threw a `DataApiBuilderException` for
an invalid `If-Match` value, the exception was thrown before entering
`HandleOperation` and the `try-catch` block within. This is where we
convert `DataApiBuilderException` into structured JSON error response.
We therefore move the `DeterminePatchPutSemantics` call inside of the
`try-catch` block within `HandleOperation`, gating the function behind a
check of the operation type so that it only applies to `Upsert` and
`UpsertIncremental` operations.

## How was this tested?

Added a test for `Put` and a test for `Patch` to validate the new
behavior.

## Sample Request(s)

Any valid `Put` or `Patch` with headers using `If-Match` with a value
other than `*`

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aniruddh Munde <anmunde@microsoft.com>
(cherry picked from commit 0cb58f0)
## Why make this change?

Closes #3268

## What is this change?

When `dab validate` or `dab start` encounters a config parsing error
(e.g. missing entities/autoentities), the CLI previously dumped the full
exception message and stack trace to stderr. This made the output noisy
and unhelpful. After this change, only a clean, descriptive validation
message is shown.

The key design changes:

- `TryParseConfig` is now a pure function that returns an `out string?
parseError` message on failure instead of writing to `Console.Error` or
`ILogger` internally. Error reporting is the caller's responsibility.
- `FileSystemRuntimeConfigLoader.TryLoadConfig` writes the `parseError`
to `Console.Error` (because config is parsed before the DI container and
logger are available, so the log buffer would never be flushed on a
parse failure) and sets an instance-scoped `IsParseErrorEmitted` flag so
CLI callers (`ConfigGenerator`) can avoid logging duplicate messages.
- `ConfigGenerator.IsConfigValid` now has an explicit early-return path
when config parsing fails (via `runtimeConfigProvider.TryGetConfig`),
using `IsParseErrorEmitted` to suppress duplicate output.
- `ValidateOptions.Handler` uses `LogError("Config is invalid.")`.
- Comments referencing which method emits the error to `Console.Error`
corrected to `TryLoadConfig` (not `TryParseConfig`).

## How was this tested?

* `ValidateConfigTests.cs` — Added
`TestValidateConfigWithNoEntitiesProducesCleanError` (new test verifying
clean error message, no stack traces).
* `EnvironmentTests.cs` — Updated
`FailureToStartEngineWhenEnvVarNamedWrong` to match the new single-line
clean stderr format.
* `EndToEndTests.cs` — Simplified assertions in
`TestExitOfRuntimeEngineWithInvalidConfig` (this test is Ignored but
updated for consistency).
* `RuntimeConfigLoaderTests.cs` — Updated
`FailLoadMultiDataSourceConfigDuplicateEntities` to assert
`loader.IsParseErrorEmitted` is true.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Souvik Ghosh <souvikofficial04@gmail.com>
(cherry picked from commit f2b4cbd)
…strict is false (#3325)

## Why make this change?

Closes #3260

## What is this change?

When request-body-strict is set to false, the OpenAPI document was still
generating separate _NoAutoPK and _NoPK component schemas for each
entity. These schemas only differ from the base entity schema by
excluding primary key fields, a distinction that is meaningless when the
request body already allows additional properties. This made the
generated OpenAPI document unnecessarily verbose and confusing for
consumers.

The `isRequestBodyStrict` flag is now threaded through `BuildPaths` and
`CreateOperations` so that POST/PUT/PATCH request body schema references
point to the base entity schema when strict mode is off. The
`CreateComponentSchemas` method now gates `_NoAutoPK` and `_NoPK` schema
generation on strict mode, and its XML documentation has been updated to
accurately describe both strict and non-strict behavior.

## How was this tested?

- [ ] Integration Tests
- [x] Unit Tests

Updated existing unit test
`RequestBodyStrict_False_OmitsRedundantSchemas` (renamed from
`RequestBodyStrict_False_AllowsExtraFields`) to verify that when
request-body-strict is false:
- `_NoAutoPK` and `_NoPK` component schemas are not generated.
- The base entity schema is still present.
- POST/PUT/PATCH operations reference the base entity schema (not
`_NoAutoPK` or `_NoPK`).

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Aniruddh Munde <anmunde@microsoft.com>
Co-authored-by: Anusha Kolan <anushakolan10@gmail.com>
(cherry picked from commit c860fc5)
## Why make this change?

Closes #3324

## What is this change?

Expand the enums for our json data type to include `integer`. Use this
new integer type in the system to json type map.

## How was this tested?

Existing test coverage.

---------

Co-authored-by: Aniruddh Munde <anmunde@microsoft.com>
(cherry picked from commit 062ddc6)
## Why make this change?

Closes #3267

## What is this change?

Alters the validation logic in the following way.

Is top-level config with data-source-files? (we call this a `Root`
config file)
├── YES
│ ├── Has datasource? → ValidateEntityPresence (same rules as non-root)
│   ├── No datasource but has entities/autoentities? → ERROR
│   └── No datasource, no entities → VALID (children provide everything)
│   └── For each child → ValidateNonRootConfig(child, filename)
│
└── NO (standalone or child config)
    ├── No datasource? → ERROR: "data source is required"
    └── Has datasource → ValidateEntityPresence

Note: A top-level config file without any children data-source files is
NOT considered a root. And an intermediary config file, ie: is a child,
that also has child configs is NOT a root. Only a top-level config with
children configs is a Root.

#### ValidateEntityPresence
Count resolved autoentities from AutoentityResolutionCounts
total = manual entities + resolved autoentities

total == 0? → ERROR: "No entities found"
total > 0 but autoentities discovered nothing? → WARN: "Autoentities
configured but none discovered"

No double messaging. If total is 0, only the error is recorded, not the
warning.

## How was this tested?

### Truth table — top-level config

Variables (`1` = present / non-empty, `0` = absent / empty):
- **DSF** — `data-source-files` present
- **DS** — `data-source` present
- **E** — manual `entities` count > 0
- **AE** — `autoentities` count > 0 (presence, *not* resolved count)

Path is determined by `IsRootConfig = (DSF == 1) && !IsChildConfig`.

| # | DSF | DS | E | AE | AE resolved | Path | Expected | Test |
|---|:---:|:--:|:-:|:--:|:-----------:|------|----------|------|
| 1 | 0 | 0 | 0 | 0 | — | Non-root | **Error**: "data source is
required" | `TestNonRootWithNoDataSourceProducesError` |
| 2 | 0 | 0 | 0 | 1 | — | Non-root | **Error**: "data source is
required" | _covered by #1 — DS check fires first_ |
| 3 | 0 | 0 | 1 | 0 | — | Non-root | **Error**: "data source is
required" | _covered by #1_ |
| 4 | 0 | 0 | 1 | 1 | — | Non-root | **Error**: "data source is
required" | _covered by #1_ |
| 5 | 0 | 1 | 0 | 0 | — | Non-root | **Error**: "No entities found" |
`TestNonRootWithDataSourceAndNoEntitiesProducesError` |
| 6a | 0 | 1 | 0 | 1 | 0 | Non-root | **Error**: "No entities found" |
`TestNonRootWithDataSourceAndAutoentitiesResolvingZeroProducesError` |
| 6b | 0 | 1 | 0 | 1 | >0 | Non-root | **Valid** |
`TestNonRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValid` |
| 7 | 0 | 1 | 1 | 0 | — | Non-root | **Valid** |
`TestNonRootWithDataSourceAndEntitiesIsValid` |
| 8a | 0 | 1 | 1 | 1 | 0 | Non-root | **Valid** + **Warn** |
`TestNonRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarning` |
| 8b | 0 | 1 | 1 | 1 | >0 | Non-root | **Valid** | _covered by #7 / #6b
combined_ |
| 9 | 1 | 0 | 0 | 0 | — | Root | **Valid** (children carry the load) |
`TestRootWithNoDataSourceAndNoEntitiesIsValid`,
`TestRootConfigWithNoDataSourceAndNoEntitiesParses` |
| 10 | 1 | 0 | 0 | 1 | — | Root | **Error**: "must not define entities
or autoentities" |
`TestRootWithNoDataSourceButAutoentitiesProducesError` |
| 11 | 1 | 0 | 1 | 0 | — | Root | **Error**: "must not define entities"
| `TestRootWithNoDataSourceButEntitiesProducesError` |
| 12 | 1 | 0 | 1 | 1 | — | Root | **Error** | _covered by #11_ |
| 13 | 1 | 1 | 0 | 0 | — | Root (with own DS) | **Error**: "No entities
found" | `TestRootWithDataSourceAndNoEntitiesProducesError` |
| 14a | 1 | 1 | 0 | 1 | 0 | Root (with own DS) | **Error**: "No entities
found" |
`TestRootWithDataSourceAndAutoentitiesResolvingZeroProducesError` |
| 14b | 1 | 1 | 0 | 1 | >0 | Root (with own DS) | **Valid** |
`TestRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValid` |
| 15 | 1 | 1 | 1 | 0 | — | Root (with own DS) | **Valid** |
`TestRootWithDataSourceAndEntitiesIsValid` |
| 16a | 1 | 1 | 1 | 1 | 0 | Root (with own DS) | **Valid** + **Warn** |
`TestRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarning` |
| 16b | 1 | 1 | 1 | 1 | >0 | Root (with own DS) | **Valid** | _covered
by #15 / #14b combined_ |

### Truth table — child config (validated when iterating
`root.ChildConfigs`)

Children are always treated as non-root regardless of their own
`data-source-files`.

| # | DS | E | AE | AE resolved | Expected | Test |
|---|:--:|:-:|:--:|:-----------:|----------|------|
| C1 | 0 | 0 | 0 | — | **Error** naming the child file: "data source is
required" | `TestChildWithNoDataSourceProducesNamedError` |
| C2 | 0 | * | * | — | **Error** naming the child file: "data source is
required" | _covered by C1_ |
| C3 | 1 | 0 | 0 | — | **Error** naming the child file: "No entities
found" | `TestChildWithDataSourceAndNoEntitiesProducesNamedError` |
| C4a | 1 | 0 | 1 | 0 | **Error** naming the child file: "No entities
found" |
`TestChildWithDataSourceAndAutoentitiesResolvingZeroProducesNamedError`
|
| C4b | 1 | 0 | 1 | >0 | **Valid** | _covered by C5 (resolved entities
behave the same as manual entities)_ |
| C5 | 1 | 1 | 0 | — | **Valid** | _implicitly via
`TestRootWithDataSourceAndEntitiesIsValid` setup_ |
| C6a | 1 | 1 | 1 | 0 | **Valid** + **Warn** naming the child file |
`TestChildWithEntitiesAndAutoentitiesResolvingZeroLogsNamedWarning` |
| C6b | 1 | 1 | 1 | >0 | **Valid** | _covered by C5_ |

### Other scenarios

| Scenario | Expected | Test |
|----------|----------|------|
| Connection-string error gates entity validation (no entity error fires
when DB unreachable) | `IsConfigValid == false` due to connection error
only | `TestValidateNonRootZeroEntitiesWithInvalidConnectionString` |
| Config with no entities parses cleanly (constructor no longer throws)
and `IsConfigValid` returns false without throwing | parse OK, validate
fails | `TestValidateConfigWithNoEntitiesProducesCleanError`
_(modified)_ |
| Root parses successfully without a data source | parse OK,
`IsRootConfig == true` |
`TestRootConfigWithNoDataSourceAndNoEntitiesParses` |
| Non-root with DS and no entities parses successfully | parse OK,
`IsRootConfig == false` |
`TestNonRootConfigWithDataSourceAndNoEntitiesParses` |
| Autoentities present but resolve to nothing — must not crash, must not
double-message with "No entities found" | no crash; only "No entities
found" if total = 0 | `ValidateAutoentitiesConfiguration` _(modified to
`isValidateOnly: true`)_ |

New tests:

`TestRootConfigWithNoDataSourceAndNoEntitiesParses` Root config (has
data-source-files) without datasource parses OK
`TestNonRootConfigWithDataSourceAndNoEntitiesParses` Non-root config
with datasource + no entities parses OK (validation catches it later)
`TestNonRootWithDataSourceAndNoEntitiesProducesError` Calls
ValidateDataSourceAndEntityPresence directly, error recorded
`TestNonRootWithNoDataSourceProducesError` No datasource, error with
"data source is required"
`TestNonRootWithDataSourceAndEntitiesIsValid` Datasource + entities, no
errors
`TestRootWithNoDataSourceAndNoEntitiesIsValid` Root with child, no own
datasource, valid
`TestRootWithNoDataSourceButEntitiesProducesError` Root with entities
but no datasource, error
`TestRootWithDataSourceAndEntitiesIsValid` Root with own datasource +
entities, valid
`TestChildWithDataSourceAndNoEntitiesProducesNamedError` Child with no
entities, error names the child file
`TestChildWithNoDataSourceProducesNamedError` Child with no datasource,
error names the child file
`TestNonRootWithDataSourceAndAutoentitiesResolvingZeroProducesError`
Non-root with only autoentities that resolve to 0
`TestNonRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValid`
Non-root with only autoentities resolving > 0 entities
`TestNonRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarning`
Non-root with manual entities + autoentities resolving 0
`TestRootWithNoDataSourceButAutoentitiesProducesError` Root with no
datasource but autoentities defined
`TestRootWithDataSourceAndNoEntitiesProducesError` Root with own
datasource and zero entities/autoentities
`TestRootWithDataSourceAndAutoentitiesResolvingZeroProducesError` Root
with own datasource and autoentities resolving 0
`TestRootWithDataSourceAndAutoentitiesResolvingEntitiesIsValid` Root
with own datasource and autoentities resolving > 0
`TestRootWithEntitiesAndAutoentitiesResolvingZeroLogsWarning` Root with
own datasource, manual entities, and autoentities resolving 0
`TestChildWithDataSourceAndAutoentitiesResolvingZeroProducesNamedError`
Child with autoentities-only resolving 0
`TestChildWithEntitiesAndAutoentitiesResolvingZeroLogsNamedWarning`
Child with manual entities + autoentities resolving 0

Modified tests:

`TestValidateConfigWithNoEntitiesProducesCleanError` Replaced main's
version (expected parse failure) with ours: parse succeeds,
IsConfigValid returns false
`ValidateAutoentitiesConfiguration` Changed to isValidateOnly: true,
asserts no crashes instead of zero errors

---------

Co-authored-by: Anusha Kolan <anushakolan10@gmail.com>
(cherry picked from commit c249436)
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This cherry-pick brings a set of REST/OpenAPI/CLI/config-validation fixes from main into release/2.0, improving HTTP semantics, generated OpenAPI output, and configuration parsing/validation behavior (including multi-config “root + data-source-files” scenarios).

Changes:

  • REST/OpenAPI: return correct 400 for invalid If-Match on PUT/PATCH; add descriptive 404 ProblemDetails for missing/invalid OpenAPI role requests; reduce OpenAPI schema verbosity when request-body-strict is false.
  • Config parsing/validation: align parent/child config handling, improve entity/autoentity validation after autoentity resolution, and refine error surfacing (clean parse errors when logger isn’t available).
  • CLI/schema: align CLI log labels with ASP.NET Core console formatter and add missing runtime.cache.level-2 + validation constraints to dab.draft.schema.json.

Reviewed changes

Copilot reviewed 37 out of 37 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/Service/Startup.cs Downgrades response-compression “enabled” log to Debug.
src/Service/HealthCheck/HealthCheckHelper.cs Guards datasource health checks when DataSource is null.
src/Service/Controllers/RestController.cs Moves If-Match semantics inside try/catch; returns descriptive 404 ProblemDetails for OpenAPI role lookups.
src/Service.Tests/UnitTests/RuntimeConfigLoaderJsonDeserializerTests.cs Updates parsing tests to assert parseError rather than logger invocations; clarifies child-file behavior docs.
src/Service.Tests/SqlTests/RestApiTests/Put/PutApiTestBase.cs Adds integration test ensuring invalid If-Match returns 400.
src/Service.Tests/SqlTests/RestApiTests/Patch/PatchApiTestBase.cs Adds integration test ensuring invalid If-Match returns 400.
src/Service.Tests/OpenApiDocumentor/StoredProcedureGeneration.cs Updates expected JSON types from numberinteger for int-like params.
src/Service.Tests/OpenApiDocumentor/RequestBodyStrictTests.cs Updates strict=false assertions to ensure redundant schemas are omitted and request bodies reference base schema.
src/Service.Tests/OpenApiDocumentor/ParameterValidationTests.cs Updates stored-proc parameter JSON type assertions to integer.
src/Service.Tests/OpenApiDocumentor/MissingRoleNotFoundTests.cs Adds integration test validating descriptive 404 ProblemDetails for missing/invalid OpenAPI roles.
src/Service.Tests/ModuleInitializer.cs Updates Verify settings to ignore newly added runtime-only RuntimeConfig members.
src/Service.Tests/Configuration/RuntimeConfigLoaderTests.cs Adds tests covering child config env-var ignore behavior and “existing but invalid child halts load”.
src/Service.Tests/Configuration/ConfigurationTests.cs Adapts tests to updated parsing/validation flows and nullable DataSource handling.
src/Core/Services/TypeHelper.cs Maps integral CLR types to JSON integer type.
src/Core/Services/OpenAPI/OpenApiDocumentor.cs Threads isRequestBodyStrict through path/op/schema generation and gates redundant schemas.
src/Core/Services/OpenAPI/JsonDataType.cs Introduces Integer JSON data type.
src/Core/Services/MetadataProviders/SqlMetadataProvider.cs Wraps non-DAB exceptions during DB connection validation as initialization errors.
src/Core/Services/MetadataProviders/MsSqlMetadataProvider.cs Tracks per-autoentity resolution counts for downstream validation.
src/Core/Services/MetadataProviders/CosmosSqlMetadataProvider.cs Adjusts for nullable DataSource (but still needs consistent null-safety).
src/Core/Configurations/RuntimeConfigValidator.cs Adds root/non-root entity presence validation after autoentity resolution; avoids GraphQL validation when datasource absent.
src/Core/Configurations/RuntimeConfigProvider.cs Updates parsing to new TryParseConfig(..., out parseError) overload (but still needs nullable-safe dereferences).
src/Config/RuntimeConfigLoader.cs Reworks parsing to return a clean parseError message instead of logging/printing stack traces.
src/Config/ObjectModel/RuntimeConfig.cs Makes DataSource nullable; adds root/child tracking and autoentity-resolution metadata; improves child-config load behavior.
src/Config/ObjectModel/MultipleCreateOptions.cs Removes trailing whitespace.
src/Config/ObjectModel/ChildConfigMetadata.cs Adds a record type for child-config metadata (validation support).
src/Config/FileSystemRuntimeConfigLoader.cs Emits clean parse errors to stderr and tracks whether they were already emitted.
src/Cli/CustomLoggerProvider.cs Aligns CLI log level labels to ASP.NET Core abbreviations and hardens color lookups.
src/Cli/ConfigGenerator.cs Adds clear CLI errors for root configs without datasources; suppresses duplicate parse-failure output (but needs nullable deref fixes).
src/Cli/Commands/ValidateOptions.cs Simplifies invalid-config message.
src/Cli.Tests/ValidateConfigTests.cs Adds extensive config-validation truth-table tests and verifies clean error paths.
src/Cli.Tests/UserDelegatedAuthRuntimeParsingTests.cs Adjusts for nullable DataSource with null-forgiveness where appropriate.
src/Cli.Tests/ModuleInitializer.cs Updates Verify ignore list for new runtime-only RuntimeConfig members.
src/Cli.Tests/EnvironmentTests.cs Updates assertions to match clean parse-error stderr output.
src/Cli.Tests/EndToEndTests.cs Updates end-to-end expectations to match new stderr/stdout behavior and nullable DataSource.
src/Cli.Tests/CustomLoggerTests.cs Adds test coverage for abbreviated log labels.
src/Cli.Tests/ConfigureOptionsTests.cs Adjusts for nullable DataSource with null-forgiveness where appropriate.
schemas/dab.draft.schema.json Adds runtime.cache.level-2 and enforces ttl-seconds minimum of 1.
Comments suppressed due to low confidence (1)

src/Core/Configurations/RuntimeConfigProvider.cs:200

  • RuntimeConfig.DataSource is now nullable, but this Initialize path still dereferences runtimeConfig.DataSource later (e.g., DatabaseType / ConnectionString). With nullable enabled + TreatWarningsAsErrors, this will produce nullable warnings and can also NRE if a config without data-source is passed. Add an explicit runtimeConfig.DataSource is null guard (with a clearer exception message) and/or use null-forgiveness after the guard so the code is both safe and compiles cleanly.
            if (string.IsNullOrEmpty(runtimeConfig.DataSource?.ConnectionString))
            {
                throw new ArgumentException($"'{nameof(runtimeConfig.DataSource.ConnectionString)}' cannot be null or empty.", nameof(runtimeConfig.DataSource.ConnectionString));
            }

Comment on lines 18 to 23
public string Schema { get; init; }

public const string DEFAULT_CONFIG_SCHEMA_LINK = "https://github.com/Azure/data-api-builder/releases/download/vmajor.minor.patch/dab.draft.schema.json";

public DataSource DataSource { get; init; }
public DataSource? DataSource { get; init; }

Comment on lines +734 to 737
DatabaseType dbType = runtimeConfig.DataSource!.DatabaseType;
string dataSourceConnectionString = runtimeConfig.DataSource.ConnectionString;
DatasourceHealthCheckConfig? datasourceHealthCheckConfig = runtimeConfig.DataSource.Health;
UserDelegatedAuthOptions? userDelegatedAuthConfig = runtimeConfig.DataSource.UserDelegatedAuth;
_databaseType = runtimeConfig.DataSource.DatabaseType;
_databaseType = runtimeConfig.DataSource!.DatabaseType;

CosmosDbNoSQLDataSourceOptions? cosmosDb = runtimeConfig.DataSource.GetTypedOptions<CosmosDbNoSQLDataSourceOptions>();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Review In Progress

Development

Successfully merging this pull request may close these issues.

5 participants