Skip to content

Conversation

@smilkuri
Copy link
Contributor

@smilkuri smilkuri commented Nov 24, 2025

Issue #, if available:

#1779
codegen v3: aws/aws-sdk-js-v3#7527

Description of changes:

--

@smilkuri smilkuri force-pushed the resolve-conflict-params branch from f3ea1fe to 13fd0f0 Compare December 1, 2025 16:16
@smilkuri smilkuri marked this pull request as ready for review December 1, 2025 16:57
@smilkuri smilkuri requested a review from a team as a code owner December 1, 2025 16:57
@smilkuri smilkuri force-pushed the resolve-conflict-params branch from cfaa5d4 to 9117008 Compare December 1, 2025 17:00
@smilkuri smilkuri force-pushed the resolve-conflict-params branch from 9117008 to 1fc37f8 Compare December 1, 2025 17:01
@smilkuri smilkuri changed the title fix: nest conflicting endpoint parameters fix: handle clientContextParam collisions with builtin config keys Dec 1, 2025
@smilkuri smilkuri force-pushed the resolve-conflict-params branch from ef3cda8 to c5f0d86 Compare December 1, 2025 20:11
Map<String, String> builtInParams = ruleSetParameterFinder.getBuiltInParams();
builtInParams.keySet().removeIf(OmitEndpointParams::isOmitted);
Set<String> knownConfigKeys = Set.of(
"apiKey", "retryStrategy", "requestHandler");
Copy link
Contributor

Choose a reason for hiding this comment

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

make this static final on the class

Copy link
Contributor

Choose a reason for hiding this comment

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

on second thought this should be handled by a separate class.

seed the class with the config keys seen in https://github.com/aws/aws-sdk-js-v3/blob/f806a2b9eded9f82d488f3d81db36b9cba9da220/private/aws-client-api-test/src/client-interface-tests/client-s3/impl/initializeWithMaximalConfiguration.ts except those specific to S3, then create a public Java static method to add keys to the list.

const nestedValue: unknown = clientContextParams?.[configKey] ?? clientContextParams?.[canonicalEndpointParamKey];
configValue = nestedValue ?? config[configKey] ?? config[canonicalEndpointParamKey];
} else {
// For built-in parameters, only check direct config properties
Copy link
Contributor

Choose a reason for hiding this comment

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

not just for built-ins, for anything other than client context params

if (isClientContextParam) {
// For client context parameters, check clientContextParams first
const clientContextParams = config.clientContextParams as Record<string, unknown> | undefined;
const nestedValue: unknown = clientContextParams?.[configKey] ?? clientContextParams?.[canonicalEndpointParamKey];
Copy link
Contributor

Choose a reason for hiding this comment

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

is there any case where the nested object does not use the canonical parameter key?

If not, there's no reason to check the configKey entry for the nested object.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so

break;
case "builtInParams":
endpointParams[name] = await createConfigValueProvider<Config>(instruction.name, name, clientConfig)();
endpointParams[name] = await createConfigValueProvider<Config>(instruction.name, name, clientConfig, false)();
Copy link
Contributor

@kuhe kuhe Dec 2, 2025

Choose a reason for hiding this comment

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

case "clientContextParams":
case "builtInParams":
  endpointParams[name] = await createConfigValueProvider<Config>(
    instruction.name, name, clientConfig, instruction.type !== "builtInParams"
  )();

options: T & ClientInputEndpointParameters
): T & ClientResolvedEndpointParameters => {
return Object.assign(options, {
apiKey: options.apiKey ?? "default-api-key",
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the main point of the fix, but this shouldn't appear here, since it will conflict with the same key potentially be added by the api key auth scheme.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is generated because the parameter has a default value set defined in @endpointRuleSet. If a default value is not defined it doesn't generate this.

type: "String",
required: true,
default: "default-custom-value",
documentation: "Custom parameter for testing",
Copy link
Contributor

Choose a reason for hiding this comment

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

add a few more client context params like boolean and I believe there is one more type which is string[], right?

add a conflicting and non-conflicting param for each type

Copy link
Contributor

Choose a reason for hiding this comment

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

and add some that don't have default values (or are they required?)

"};",
() -> {
writer.write("defaultSigningName: string;");
if (!customContextParams.isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if (!customContextParams.isEmpty()) {
if (ruleSetParameterFinder.hasCustomClientContextParams()) {

parameters.accept(new RuleSetParametersVisitor(
writer, customContextParams, true));
});
writer.dedent();
Copy link
Contributor

Choose a reason for hiding this comment

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

writer.indent();
ruleSetParameterFinder.writeResolvedConfigCustomClientContextParams(writer);
writer.dedent();

}
);
// Generate clientContextParamDefaults only if there are customer context params
if (!customContextParams.isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

if (ruleSetParameterFinder.hasCustomClientContextParams()) {
  ruleSetParameterFinder.writeNestedClientContextParamDefaults(writer);
}

settings.getDefaultSigningName()
);
// Only generate clientContextParams if there are customer context params
if (!customContextParams.isEmpty()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

ruleSetParameterFinder.writeConfigResolverNestedClientContextParams(writer);

@documentation("xyz interfaces")
@clientContextParams(
apiKey: { type: "string", documentation: "API key for authentication" }
customParam: { type: "string", documentation: "Custom parameter" }
Copy link
Contributor

Choose a reason for hiding this comment

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

going to comment again here since this is the source file and ruleset.ts is generated:

add some more client context params with varying permutations:

  • conflicting / non-conflicting
  • string / string[] / boolean
  • has default + required / no default + optional

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.

2 participants