Skip to content

Conversation

@PotatoWKY
Copy link
Contributor

Summary

This PR migrates the DataZone custom API client from the deprecated AWS SDK v2 generator pattern to standalone AWS SDK v3-compatible packages. This migration is required as part of the broader AWS Toolkit repository migration from SDK v2 to v3.

The AWS Toolkit VSCode repository is deprecating the centralized generateServiceClient.ts script that generates TypeScript clients from service JSON definitions. The SageMaker Unified Studio (SMUS) team currently uses this v2 generator for DataZone Custom API.

Solution

  • Created standalone package @amzn/datazone-custom-client with SDK v3 patterns
  • Updated DataZoneCustomClientHelper to use SDK v3 client initialization and Command pattern
  • Migrated from client.methodName().promise() to client.send(new Command()) pattern
  • Updated credential provider to use SDK v3 async credential provider function
  • Updated imports to use new standalone package types and commands
  • Updated test files to mock SDK v3 send() method instead of v2 .promise() pattern
  • Removed dependency for DataZone Custom API on the deprecated generateServiceClient.ts script

  • Treat all work as PUBLIC. Private feature/x branches will not be squash-merged at release time.
  • Your code changes must meet the guidelines in CONTRIBUTING.md.
  • License: I confirm that my contribution is made under the terms of the Apache 2.0 license.

@PotatoWKY PotatoWKY requested a review from a team as a code owner December 11, 2025 01:22
@PotatoWKY PotatoWKY force-pushed the sdk-upgrade-datazone branch from 2890cdb to 0f08f21 Compare December 11, 2025 01:23
@PotatoWKY PotatoWKY changed the title Upgrade sdk v2 to sdk v3 - DataZoneCustomClient feat(smus): Upgrade sdk v2 to sdk v3 - DataZoneCustomClient Dec 11, 2025
@PotatoWKY PotatoWKY closed this Dec 11, 2025
@PotatoWKY PotatoWKY reopened this Dec 11, 2025
@github-actions
Copy link

  • This pull request implements a feat or fix, so it must include a changelog entry (unless the fix is for an unreleased feature). Review the changelog guidelines.
    • Note: beta or "experiment" features that have active users should announce fixes in the changelog.
    • If this is not a feature or fix, use an appropriate type from the title guidelines. For example, telemetry-only changes should use the telemetry type.

Copy link
Contributor

@vpbhargav vpbhargav left a comment

Choose a reason for hiding this comment

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

Thanks for making these changes! How are we testing and ensuring there is no regression?

Comment on lines +107 to +117
const awsCredentialProvider = async () => {
const credentials = await this.credentialProvider.getCredentials()
return {
accessKeyId: credentials.accessKeyId,
secretAccessKey: credentials.secretAccessKey,
sessionToken: credentials.sessionToken,
expiration: credentials.expiration,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This wrapper needed? Unable to pass this.credentialProvider directly to the clientConfig? Seems like it but just want to confirm.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it is needed. I am not Typescript pro, but here is my understanding:

  • passing this.credentialProvider would only pass the method,
  • with the wrapper it also passes the instance

we would need the correct instance to get the credentials
Inspired by @liuzulin:
https://github.com/aws/aws-toolkit-vscode/blame/20a5e850bc483e0d649eddf1880014e2873ca565/packages/core/src/sagemakerunifiedstudio/shared/client/s3Client.ts#L159

listDomains: sinon.stub().returns({
promise: () => Promise.resolve(mockResponse),
}),
send: sinon.stub().resolves(mockResponse),
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we able to be specific with which method is being called for this sub as well? listDomains in this case?

assert.deepStrictEqual(mockDataZoneClient.getDomain.firstCall.args[0], {
identifier: mockDomainId,
})
assert.ok(mockDataZoneClient.send.calledOnce)
Copy link
Contributor

Choose a reason for hiding this comment

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

These assertion are not the same. We were validating input params earlier and now we are just validating that some send call is made. Are we able to maintain the old assertions?

Same for other places in test too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah you are right, the verifications are over simplified. let me add some more detailed validation

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is not addressed still right? I am not seeing any changes here in diff?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure why the diff shows nothing, maybe due to force push? I added back the old assertions, except for we are validating send.calledOnce instead of getDomain.calledOnce now

domainId: mockDomainId,
id: 'gp_profile1',
status: 'ACTIVATED',
status: 'ASSIGNED',
Copy link
Contributor

Choose a reason for hiding this comment

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

Why did this need to change? Previous test was wrong?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it was wrong, it would be either UNASSIGNED or ASSIGNED

@PotatoWKY
Copy link
Contributor Author

Thanks for making these changes! How are we testing and ensuring there is no regression?

I did sanity test for each of the 3 SDK upgrade PRs, I think we would also want to let the team test the prerelease vsix after the 3 PRs are merged.

@PotatoWKY PotatoWKY force-pushed the sdk-upgrade-datazone branch 5 times, most recently from 03eaff9 to 66b4f43 Compare December 17, 2025 01:10
*/
export class DataZoneCustomClientHelper {
private datazoneCustomClient: DataZoneCustomClient | undefined
private datazoneCustomClient: DataZone | undefined
Copy link
Contributor

Choose a reason for hiding this comment

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

wondering if we can import it as DataZoneCustomClient so we can keep the naming here, it aligns with the variable and cause less confusion

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'm not confidence if this is the best practice but there is my thought:
I intentionally changed this to DataZoneCustomClient -> DataZone to maintain the original type name because I think the extra step of renaming would cause more confusion. It looks cleaner to me, what do you think?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think renaming would cause more confusion: renaming keeps the change in a single place: in the import statement. and helps to keep all the rest of places same as previous. I think it cause less confusion.
And I don't think it's correct to say it's "cleaner". indeed it seems more "cleaner" in this single file. But we also have a regular DataZoneClient which also have a DataZone type. If working across both files, this actually cause more confusion.
But anyway I approved the PR as I don't think this is a blocker issue and we can loop back on this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah that make sense!

this.logger.debug(
`DataZoneCustomClientHelper: Using custom DataZone endpoint from settings: ${endpoint}`
)
const clientConfig: any = {
Copy link
Contributor

Choose a reason for hiding this comment

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

avoid using any as type

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for catching that

.promise()
const command = new ListDomainsCommand({
maxResults: options?.maxResults,
status: options?.status as any,
Copy link
Contributor

Choose a reason for hiding this comment

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

avoid using any as type, please also check other places that you changed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks for catching that. Checked these are the only 2 any type in my change for this PR

@PotatoWKY PotatoWKY changed the title feat(smus): Upgrade sdk v2 to sdk v3 - DataZoneCustomClient deps(smus): Upgrade sdk v2 to sdk v3 - DataZoneCustomClient Jan 6, 2026
@PotatoWKY PotatoWKY force-pushed the sdk-upgrade-datazone branch from 66b4f43 to e8ffa59 Compare January 6, 2026 23:43
@laileni-aws laileni-aws enabled auto-merge (squash) January 15, 2026 00:07
auto-merge was automatically disabled January 15, 2026 00:29

Head branch was pushed to by a user without write access

@laileni-aws laileni-aws enabled auto-merge (squash) January 15, 2026 00:37
@laileni-aws laileni-aws merged commit a4eb4a4 into aws:master Jan 15, 2026
34 checks passed
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.

5 participants