[management] Code generation: update services and models#1829
[management] Code generation: update services and models#1829AdyenAutomationBot wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds support for donation campaigns, nonprofits, and related settings to the Adyen Management API client, introducing several new models, JSON converters, and a new service. Feedback on the changes identifies a runtime fragility issue in ScheduleTerminalActionsRequestActionDetails.cs where jsonSerializerOptions.GetConverter should be used instead of Converters.First. Additionally, missing Models. namespace prefixes in ClientUtils.cs should be added for consistency, and the properties PresentCardTimeoutMs and PromptTimeoutMs in InPersonDonationSettingsUpdate.cs should be corrected from Object? to long? to maintain type safety.
| if (scheduleTerminalActionsRequestActionDetails.ForceRebootDetails != null) | ||
| JsonSerializer.Serialize(writer, scheduleTerminalActionsRequestActionDetails.ForceRebootDetails, jsonSerializerOptions); | ||
| { | ||
| ForceRebootDetailsJsonConverter forceRebootDetailsJsonConverter = (ForceRebootDetailsJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(scheduleTerminalActionsRequestActionDetails.ForceRebootDetails.GetType())); | ||
| forceRebootDetailsJsonConverter.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.ForceRebootDetails, jsonSerializerOptions); | ||
| } | ||
|
|
||
| if (scheduleTerminalActionsRequestActionDetails.InstallAndroidAppDetails != null) | ||
| JsonSerializer.Serialize(writer, scheduleTerminalActionsRequestActionDetails.InstallAndroidAppDetails, jsonSerializerOptions); | ||
| { | ||
| InstallAndroidAppDetailsJsonConverter installAndroidAppDetailsJsonConverter = (InstallAndroidAppDetailsJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(scheduleTerminalActionsRequestActionDetails.InstallAndroidAppDetails.GetType())); | ||
| installAndroidAppDetailsJsonConverter.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.InstallAndroidAppDetails, jsonSerializerOptions); | ||
| } | ||
|
|
||
| if (scheduleTerminalActionsRequestActionDetails.InstallAndroidCertificateDetails != null) | ||
| JsonSerializer.Serialize(writer, scheduleTerminalActionsRequestActionDetails.InstallAndroidCertificateDetails, jsonSerializerOptions); | ||
| { | ||
| InstallAndroidCertificateDetailsJsonConverter installAndroidCertificateDetailsJsonConverter = (InstallAndroidCertificateDetailsJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(scheduleTerminalActionsRequestActionDetails.InstallAndroidCertificateDetails.GetType())); | ||
| installAndroidCertificateDetailsJsonConverter.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.InstallAndroidCertificateDetails, jsonSerializerOptions); | ||
| } | ||
|
|
||
| if (scheduleTerminalActionsRequestActionDetails.ReleaseUpdateDetails != null) | ||
| JsonSerializer.Serialize(writer, scheduleTerminalActionsRequestActionDetails.ReleaseUpdateDetails, jsonSerializerOptions); | ||
| { | ||
| ReleaseUpdateDetailsJsonConverter releaseUpdateDetailsJsonConverter = (ReleaseUpdateDetailsJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(scheduleTerminalActionsRequestActionDetails.ReleaseUpdateDetails.GetType())); | ||
| releaseUpdateDetailsJsonConverter.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.ReleaseUpdateDetails, jsonSerializerOptions); | ||
| } | ||
|
|
||
| if (scheduleTerminalActionsRequestActionDetails.UninstallAndroidAppDetails != null) | ||
| JsonSerializer.Serialize(writer, scheduleTerminalActionsRequestActionDetails.UninstallAndroidAppDetails, jsonSerializerOptions); | ||
| { | ||
| UninstallAndroidAppDetailsJsonConverter uninstallAndroidAppDetailsJsonConverter = (UninstallAndroidAppDetailsJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(scheduleTerminalActionsRequestActionDetails.UninstallAndroidAppDetails.GetType())); | ||
| uninstallAndroidAppDetailsJsonConverter.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.UninstallAndroidAppDetails, jsonSerializerOptions); | ||
| } | ||
|
|
||
| if (scheduleTerminalActionsRequestActionDetails.UninstallAndroidCertificateDetails != null) | ||
| JsonSerializer.Serialize(writer, scheduleTerminalActionsRequestActionDetails.UninstallAndroidCertificateDetails, jsonSerializerOptions); | ||
| /* | ||
| writer.WriteStartObject(); | ||
| */ | ||
| { | ||
| UninstallAndroidCertificateDetailsJsonConverter uninstallAndroidCertificateDetailsJsonConverter = (UninstallAndroidCertificateDetailsJsonConverter) jsonSerializerOptions.Converters.First(c => c.CanConvert(scheduleTerminalActionsRequestActionDetails.UninstallAndroidCertificateDetails.GetType())); | ||
| uninstallAndroidCertificateDetailsJsonConverter.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.UninstallAndroidCertificateDetails, jsonSerializerOptions); | ||
| } | ||
|
|
There was a problem hiding this comment.
Using jsonSerializerOptions.Converters.First(...) to retrieve the converter is highly fragile and will throw an InvalidOperationException at runtime if the converter is not explicitly registered in the Converters list (for example, when using custom or default JsonSerializerOptions in ASP.NET Core).
Since the models are decorated with [JsonConverter(typeof(...))], the standard and robust way to retrieve the converter is using jsonSerializerOptions.GetConverter(Type). This built-in method correctly resolves converters from all sources (explicit list, attributes, and built-in defaults) without throwing exceptions.
if (scheduleTerminalActionsRequestActionDetails.ForceRebootDetails != null)
{
var forceRebootDetailsJsonConverter = jsonSerializerOptions.GetConverter(typeof(ForceRebootDetails)) as ForceRebootDetailsJsonConverter;
forceRebootDetailsJsonConverter?.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.ForceRebootDetails, jsonSerializerOptions);
}
if (scheduleTerminalActionsRequestActionDetails.InstallAndroidAppDetails != null)
{
var installAndroidAppDetailsJsonConverter = jsonSerializerOptions.GetConverter(typeof(InstallAndroidAppDetails)) as InstallAndroidAppDetailsJsonConverter;
installAndroidAppDetailsJsonConverter?.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.InstallAndroidAppDetails, jsonSerializerOptions);
}
if (scheduleTerminalActionsRequestActionDetails.InstallAndroidCertificateDetails != null)
{
var installAndroidCertificateDetailsJsonConverter = jsonSerializerOptions.GetConverter(typeof(InstallAndroidCertificateDetails)) as InstallAndroidCertificateDetailsJsonConverter;
installAndroidCertificateDetailsJsonConverter?.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.InstallAndroidCertificateDetails, jsonSerializerOptions);
}
if (scheduleTerminalActionsRequestActionDetails.ReleaseUpdateDetails != null)
{
var releaseUpdateDetailsJsonConverter = jsonSerializerOptions.GetConverter(typeof(ReleaseUpdateDetails)) as ReleaseUpdateDetailsJsonConverter;
releaseUpdateDetailsJsonConverter?.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.ReleaseUpdateDetails, jsonSerializerOptions);
}
if (scheduleTerminalActionsRequestActionDetails.UninstallAndroidAppDetails != null)
{
var uninstallAndroidAppDetailsJsonConverter = jsonSerializerOptions.GetConverter(typeof(UninstallAndroidAppDetails)) as UninstallAndroidAppDetailsJsonConverter;
uninstallAndroidAppDetailsJsonConverter?.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.UninstallAndroidAppDetails, jsonSerializerOptions);
}
if (scheduleTerminalActionsRequestActionDetails.UninstallAndroidCertificateDetails != null)
{
var uninstallAndroidCertificateDetailsJsonConverter = jsonSerializerOptions.GetConverter(typeof(UninstallAndroidCertificateDetails)) as UninstallAndroidCertificateDetailsJsonConverter;
uninstallAndroidCertificateDetailsJsonConverter?.WriteProperties(writer, scheduleTerminalActionsRequestActionDetails.UninstallAndroidCertificateDetails, jsonSerializerOptions);
}| if (obj is Models.CampaignStatusTransition campaignStatusTransition) | ||
| return CampaignStatusTransition.ToJsonValue(campaignStatusTransition); |
There was a problem hiding this comment.
The return statement is missing the Models. prefix, which is inconsistent with the rest of the file (e.g., Models.AndroidApp.StatusEnum.ToJsonValue on line 132). If the Adyen.Management.Models namespace is not fully imported, this will also cause a compilation error. Please add the Models. prefix for consistency and safety.
if (obj is Models.CampaignStatusTransition campaignStatusTransition)
return Models.CampaignStatusTransition.ToJsonValue(campaignStatusTransition);| if (obj is Models.DisplayTextField displayTextField) | ||
| return DisplayTextField.ToJsonValue(displayTextField); | ||
| if (obj is Models.DonationCampaignStatus donationCampaignStatus) | ||
| return DonationCampaignStatus.ToJsonValue(donationCampaignStatus); | ||
| if (obj is Models.DonationFlow donationFlow) | ||
| return DonationFlow.ToJsonValue(donationFlow); | ||
| if (obj is Models.DonationType donationType) | ||
| return DonationType.ToJsonValue(donationType); |
There was a problem hiding this comment.
These return statements are missing the Models. prefix, which is inconsistent with the rest of the file. Please add the Models. prefix to ensure consistency and avoid potential compilation errors.
if (obj is Models.DisplayTextField displayTextField)
return Models.DisplayTextField.ToJsonValue(displayTextField);
if (obj is Models.DonationCampaignStatus donationCampaignStatus)
return Models.DonationCampaignStatus.ToJsonValue(donationCampaignStatus);
if (obj is Models.DonationFlow donationFlow)
return Models.DonationFlow.ToJsonValue(donationFlow);
if (obj is Models.DonationType donationType)
return Models.DonationType.ToJsonValue(donationType);| [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] | ||
| public Option<Object?> _PresentCardTimeoutMsOption { get; private set; } | ||
|
|
||
| /// <summary> | ||
| /// Required if `donationFlow` is set to **twoStep**. The time, in milliseconds, that the terminal waits for the shopper to present their card. Defaults to **10000** (10 seconds). Range: 5000 to 15000. | ||
| /// </summary> | ||
| /// <value>Required if `donationFlow` is set to **twoStep**. The time, in milliseconds, that the terminal waits for the shopper to present their card. Defaults to **10000** (10 seconds). Range: 5000 to 15000.</value> | ||
| [JsonPropertyName("presentCardTimeoutMs")] | ||
| public Object? PresentCardTimeoutMs { get { return this._PresentCardTimeoutMsOption; } set { this._PresentCardTimeoutMsOption = new(value); } } | ||
|
|
||
| /// <summary> | ||
| /// This is used to track if an optional field is set. If set, <see cref="PromptTimeoutMs"/> will be populated. | ||
| /// </summary> | ||
| [JsonIgnore] | ||
| [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] | ||
| public Option<Object?> _PromptTimeoutMsOption { get; private set; } | ||
|
|
||
| /// <summary> | ||
| /// The time, in milliseconds, that the terminal waits for the shopper to make a selection on the donation screen. Defaults to **10000** (10 seconds). Range: 5000 to 15000. | ||
| /// </summary> | ||
| /// <value>The time, in milliseconds, that the terminal waits for the shopper to make a selection on the donation screen. Defaults to **10000** (10 seconds). Range: 5000 to 15000.</value> | ||
| [JsonPropertyName("promptTimeoutMs")] |
There was a problem hiding this comment.
The properties PresentCardTimeoutMs and PromptTimeoutMs are generated with the type Object? instead of long? (or int?). This is inconsistent with InPersonDonationSettings.cs where they are correctly typed as long?, and it breaks type safety for users configuring these timeouts. Please update their types to long? (and update the corresponding JSON converter methods in this file).
public Option<long?> _PresentCardTimeoutMsOption { get; private set; }
/// <summary>
/// Required if `donationFlow` is set to **twoStep**. The time, in milliseconds, that the terminal waits for the shopper to present their card. Defaults to **10000** (10 seconds). Range: 5000 to 15000.
/// </summary>
/// <value>Required if `donationFlow` is set to **twoStep**. The time, in milliseconds, that the terminal waits for the shopper to present their card. Defaults to **10000** (10 seconds). Range: 5000 to 15000.</value>
[JsonPropertyName(c9fa0d5 to
04be2ce
Compare
04be2ce to
e10a901
Compare
This PR contains the automated changes for the
managementservice.The commit history of this PR reflects the
adyen-openapicommits that have been applied.