-
Notifications
You must be signed in to change notification settings - Fork 136
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(maintenance): add powertools to user-agent in SDK clients (#1567)
* add custom user agent middleware * remove singleton for ddb client, add useragent in constructor * remove conditional, because SDK will always resolve user-agent header * simplify test * remove retry, no longer needed * remove ua from idempotency, will be done in separate PR * review changes * revert client lazy loading * Revert "remove ua from idempotency, will be done in separate PR" This reverts commit bdda143. * revert the revert, misunderstanding * add explicit ts-ignore instead of the entire file * parameterized tests for useragent * in case of failure, warn and don't block user code * add test to check if middleware absorbs an error and continue * add more client to useragent test * fix imports
- Loading branch information
Alexander Schueren
authored
Jul 3, 2023
1 parent
78721c2
commit f934757
Showing
9 changed files
with
188 additions
and
40 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { PT_VERSION } from './version'; | ||
|
||
/** | ||
* @internal | ||
*/ | ||
const EXEC_ENV = process.env.AWS_EXECUTION_ENV || 'NA'; | ||
const middlewareOptions = { | ||
relation: 'after', | ||
toMiddleware: 'getUserAgentMiddleware', | ||
name: 'addPowertoolsToUserAgent', | ||
tags: ['POWERTOOLS', 'USER_AGENT'], | ||
}; | ||
|
||
/** | ||
* @internal | ||
* returns a middleware function for the MiddlewareStack, that can be used for the SDK clients | ||
* @param feature | ||
*/ | ||
const customUserAgentMiddleware = (feature: string) => { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
return (next, _context) => async (args) => { | ||
const powertoolsUserAgent = `PT/${feature}/${PT_VERSION} PTEnv/${EXEC_ENV}`; | ||
args.request.headers[ | ||
'user-agent' | ||
] = `${args.request.headers['user-agent']} ${powertoolsUserAgent}`; | ||
|
||
return await next(args); | ||
}; | ||
}; | ||
|
||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
const addUserAgentMiddleware = (client, feature: string): void => { | ||
try { | ||
client.middlewareStack.addRelativeTo( | ||
customUserAgentMiddleware(feature), | ||
middlewareOptions | ||
); | ||
} catch (e) { | ||
console.warn('Failed to add user agent middleware', e); | ||
} | ||
}; | ||
|
||
export { addUserAgentMiddleware }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
// this file is auto generated, do not modify | ||
export const PT_VERSION = '1.11.0'; |
109 changes: 109 additions & 0 deletions
109
packages/commons/tests/unit/userAgentMiddleware.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import { addUserAgentMiddleware } from '../../src/userAgentMiddleware'; | ||
import { InvokeCommand, LambdaClient } from '@aws-sdk/client-lambda'; | ||
import { DynamoDBClient } from '@aws-sdk/client-dynamodb'; | ||
import { ScanCommand } from '@aws-sdk/lib-dynamodb'; | ||
import { GetParameterCommand, SSMClient } from '@aws-sdk/client-ssm'; | ||
import { version as PT_VERSION } from '../../package.json'; | ||
import { AppConfigDataClient } from '@aws-sdk/client-appconfigdata'; | ||
import { | ||
GetSecretValueCommand, | ||
SecretsManagerClient, | ||
} from '@aws-sdk/client-secrets-manager'; | ||
|
||
const options = { | ||
region: 'us-east-1', | ||
endpoint: 'http://localhost:9001', | ||
credentials: { | ||
accessKeyId: 'test', | ||
secretAccessKey: 'test', | ||
sessionToken: 'test', | ||
}, | ||
}; | ||
|
||
describe('Given a client of instance: ', () => { | ||
it.each([ | ||
{ | ||
name: 'LambdaClient', | ||
client: new LambdaClient(options), | ||
command: new InvokeCommand({ FunctionName: 'test', Payload: '' }), | ||
}, | ||
{ | ||
name: 'DynamoDBClient', | ||
client: new DynamoDBClient(options), | ||
command: new ScanCommand({ TableName: 'test' }), | ||
}, | ||
{ | ||
name: 'SSMClient', | ||
client: new SSMClient(options), | ||
command: new GetParameterCommand({ Name: 'test' }), | ||
}, | ||
{ | ||
name: 'AppConfigDataClient', | ||
client: new AppConfigDataClient(options), | ||
command: new GetParameterCommand({ Name: 'test' }), | ||
}, | ||
{ | ||
name: 'SecretsManagerClient', | ||
client: new SecretsManagerClient(options), | ||
command: new GetSecretValueCommand({ SecretId: 'test' }), | ||
}, | ||
])( | ||
`using $name, add powertools user agent to request header at the end`, | ||
async ({ client, command }) => { | ||
addUserAgentMiddleware(client, 'my-feature'); | ||
|
||
expect(client.middlewareStack.identify()).toContain( | ||
'addPowertoolsToUserAgent: POWERTOOLS,USER_AGENT' | ||
); | ||
|
||
client.middlewareStack.addRelativeTo( | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
(next) => (args) => { | ||
const userAgent = args?.request?.headers['user-agent']; | ||
expect(userAgent).toContain(`PT/my-feature/${PT_VERSION} PTEnv/NA`); | ||
// make sure it's at the end of the user agent | ||
expect( | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
userAgent | ||
?.split(' ') | ||
.slice(userAgent?.split(' ').length - 2) // take the last to entries of the user-agent header | ||
.join(' ') | ||
).toEqual(`PT/my-feature/${PT_VERSION} PTEnv/NA`); | ||
|
||
return next(args); | ||
}, | ||
{ | ||
relation: 'after', | ||
toMiddleware: 'addPowertoolsToUserAgent', | ||
name: 'testUserAgentHeader', | ||
tags: ['TEST'], | ||
} | ||
); | ||
|
||
try { | ||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment | ||
// @ts-ignore | ||
await client.send(command); | ||
} catch (e) { | ||
if (e instanceof Error && e.name === 'JestAssertionError') { | ||
throw e; | ||
} | ||
} | ||
} | ||
); | ||
|
||
it('should not throw erro, when client fails to add middleware', () => { | ||
// create mock client that throws error when adding middleware | ||
const client = { | ||
middlewareStack: { | ||
addRelativeTo: () => { | ||
throw new Error('test'); | ||
}, | ||
}, | ||
}; | ||
|
||
expect(() => addUserAgentMiddleware(client, 'my-feature')).not.toThrow(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters