Skip to content

Conversation

THardy98
Copy link
Contributor

What was changed

Add environment configuration feature

  1. Closes [Feature Request] Environment Configuration #490

  2. How was this tested:
    Integration test suite ClientConfigTests.cs

  3. Any docs updates needed?
    Yes

@THardy98
Copy link
Contributor Author

Relies on temporalio/sdk-core#986

@THardy98 THardy98 marked this pull request as ready for review August 26, 2025 20:06
@THardy98 THardy98 requested a review from a team as a code owner August 26, 2025 20:06
- Convert ClientConfig, ClientConfigProfile, and ClientConfigTls to record types
- Remove ICloneable interface (records have built-in cloning)
- Use private init setters instead of private set
- Replace Dictionary parameters with IReadOnlyDictionary in public API

Replace JSON serialization with record serialization

- Replace ToJson()/FromJson() methods with ToRecord()/FromRecord() methods
- Create ClientConfigTlsRecord and ClientConfigProfileRecord for TOML structure
- Support conversion between config objects and TOML-ready record structures

Rename namespace from Configuration to EnvConfig

- Change namespace: Temporalio.Client.Configuration → Temporalio.Client.EnvConfig

Rename ClientConfig class to ClientEnvConfig

- Rename ClientConfig → ClientEnvConfig
- Update all references in tests and documentation
- Rename file ClientConfig.cs → ClientEnvConfig.cs
- Renaming EnvProfile -> ConfigProfile

Fix TLS disabled tri-state and profile not found behavior in environment config

- Change Tls.Disabled from bool to bool? to support tri-state behavior (null/true/false)
- Consolidate DataSource class back into ClientEnvConfig.cs
- Add test for tri-state TLS behavior and profile resolution
- Update profile loading logic to match Rust core behavior:
  - profile=null with missing "default" → return empty profile
  - profile="default" with missing "default" → throw exception
Copy link
Member

@cretz cretz left a comment

Choose a reason for hiding this comment

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

Is this ready for re-review?

@THardy98
Copy link
Contributor Author

Is this ready for re-review?

Yes, RFR. Will resolve the above comments

/// Convert to a record structure that can be used for TOML serialization.
/// </summary>
/// <returns>Dictionary mapping profile names to their record representations.</returns>
public IReadOnlyDictionary<string, ProfileRecord> ToRecord()
Copy link
Member

Choose a reason for hiding this comment

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

I wouldn't necessarily call this a "record", maybe ToDictionary? Arguably across SDKs this would be a dictionary with a single "profiles" entry if we wanted to properly match TOML, but I see we didn't really do that anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed to ToDictionary.

wrt changing to a single "profiles" entry, if it's something we care about I can open some PRs once this is in

Comment on lines 177 to 178
Dictionary<string, object?> dict => dict,
JsonElement el => JsonSerializer.Deserialize<Dictionary<string, object?>>(el.GetRawText(), JsonOptions),
Copy link
Member

Choose a reason for hiding this comment

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

Which situations is this one vs the other? Doesn't make sense IMO to have a forgiving parser for our own internal JSON format (not completely against the use of JSON to pass across Core, just a bit abnormal).

Copy link
Contributor Author

@THardy98 THardy98 Sep 17, 2025

Choose a reason for hiding this comment

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

Yeah - I was having trouble deserializing the incoming JSON properly (nested JSON) so had this as a fallback which worked. Not very nice though.

I've removed this in favor of actual JSON DTO objects, much cleaner.

/// </summary>
/// <param name="record">The record to convert from.</param>
/// <returns>Profile configuration instance.</returns>
public static ConfigProfile FromRecord(ProfileRecord record)
Copy link
Member

Choose a reason for hiding this comment

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

Why a "record" instead of a dictionary? That record won't necessarily serialize to TOML correctly which is the purpose of this IIRC

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why is it the case that a record won't serialize to TOML correctly? I haven't seen anything on this.

Copy link
Member

@cretz cretz Sep 18, 2025

Choose a reason for hiding this comment

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

Depends on the TOML library in use on how it handles PascalCased properties and such, but even if it can, users will have to know to set the setting to convert to underscore-based names and such. If you give/accept a dictionary (of dictionaries/lists/primitives), you can control the key names. And as a bonus you don't have to have new classes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Have changed this to use dictionaries instead of records

@THardy98 THardy98 requested a review from cretz September 19, 2025 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Feature Request] Environment Configuration
2 participants