Skip to content

Commit b76f0e4

Browse files
committed
review: remove unnecessary S3 client caching in AssetProxy
1 parent 40632c8 commit b76f0e4

File tree

2 files changed

+35
-60
lines changed

2 files changed

+35
-60
lines changed

src/lib/asset-proxy.js

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { NotFoundError, ValidationError, ForbiddenError } from './errors.js'
77
const VIRTUAL_HOST_PATTERN = /^([^.]+)\.s3(?:\.([^.]+))?\.amazonaws\.com$/
88
const PATH_STYLE_PATTERN = /^s3(?:[.-]([^.]+))?\.amazonaws\.com$/
99

10+
const s3Client = s3()
11+
1012
export const ALTERNATE_ASSETS_EXTENSION = 'https://stac-extensions.github.io/alternate-assets/v1.2.0/schema.json'
1113

1214
export const BucketOption = Object.freeze({
@@ -112,7 +114,6 @@ const determineS3Region = (asset, itemOrCollection) => {
112114
export class AssetProxy {
113115
constructor() {
114116
this.bucketsCache = null
115-
this.s3ClientCache = new Map()
116117
this.bucketOption = process.env['ASSET_PROXY_BUCKET_OPTION'] || 'NONE'
117118
this.bucketList = process.env['ASSET_PROXY_BUCKET_LIST']
118119
this.urlExpiry = parseInt(process.env['ASSET_PROXY_URL_EXPIRY'] || '300', 10)
@@ -139,10 +140,8 @@ export class AssetProxy {
139140

140141
case BucketOption.ALL_BUCKETS_IN_ACCOUNT:
141142
try {
142-
const region = process.env['AWS_REGION'] || 'us-west-2'
143-
const client = this.getS3Client(region)
144143
const command = new ListBucketsCommand({})
145-
const response = await client.send(command)
144+
const response = await s3Client.send(command)
146145
const bucketNames = response.Buckets?.map((b) => b.Name)
147146
?.filter((name) => typeof name === 'string') || []
148147
this.bucketsCache = new Set(bucketNames)
@@ -158,20 +157,6 @@ export class AssetProxy {
158157
}
159158
}
160159

161-
/**
162-
* @param {string} region - AWS region
163-
* @returns {Object} S3 client instance
164-
*/
165-
getS3Client(region) {
166-
if (this.s3ClientCache.has(region)) {
167-
return this.s3ClientCache.get(region)
168-
}
169-
170-
const client = s3({ region })
171-
this.s3ClientCache.set(region, client)
172-
return client
173-
}
174-
175160
/**
176161
* @returns {boolean}
177162
*/
@@ -280,20 +265,18 @@ export class AssetProxy {
280265
/**
281266
* @param {string} bucket - S3 bucket name
282267
* @param {string} key - S3 object key
283-
* @param {string} region - AWS region
268+
* @param {string} region - AWS region of the S3 bucket
284269
* @returns {Promise<string>} Pre-signed URL
285270
*/
286271
async createPresignedUrl(bucket, key, region) {
287-
const client = this.getS3Client(region)
288-
289272
const command = new GetObjectCommand({
290273
Bucket: bucket,
291274
Key: key,
292275
RequestPayer: 'requester'
293276
})
294277

295-
const presignedUrl = await getSignedUrl(client, command, {
296-
expiresIn: this.urlExpiry
278+
const presignedUrl = await getSignedUrl(s3Client, command, {
279+
expiresIn: this.urlExpiry, signingRegion: region
297280
})
298281

299282
logger.debug('Generated pre-signed URL for asset', {

tests/unit/test-asset-proxy.js

Lines changed: 29 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
// @ts-nocheck
22

33
import test from 'ava'
4+
import { mockClient } from 'aws-sdk-client-mock'
5+
import { S3Client, ListBucketsCommand } from '@aws-sdk/client-s3'
46
import { AssetProxy, BucketOption, ALTERNATE_ASSETS_EXTENSION } from '../../src/lib/asset-proxy.js'
57

8+
const s3Mock = mockClient(S3Client)
9+
10+
test.beforeEach(() => {
11+
s3Mock.reset()
12+
})
13+
614
test('BucketOption - exports expected constants', (t) => {
715
t.is(BucketOption.NONE, 'NONE')
816
t.is(BucketOption.ALL, 'ALL')
@@ -80,19 +88,14 @@ test('AssetProxy - initialize() with ALL_BUCKETS_IN_ACCOUNT mode fetches buckets
8088
process.env['ASSET_PROXY_BUCKET_OPTION'] = 'ALL_BUCKETS_IN_ACCOUNT'
8189
process.env['AWS_REGION'] = 'us-west-2'
8290

83-
const proxy = new AssetProxy()
84-
85-
const mockS3Client = {
86-
send: async () => ({
87-
Buckets: [
88-
{ Name: 'bucket-1' },
89-
{ Name: 'bucket-2' },
90-
]
91-
})
92-
}
93-
94-
proxy.getS3Client = () => mockS3Client
91+
s3Mock.on(ListBucketsCommand).resolves({
92+
Buckets: [
93+
{ Name: 'bucket-1' },
94+
{ Name: 'bucket-2' },
95+
]
96+
})
9597

98+
const proxy = new AssetProxy()
9699
await proxy.initialize()
97100

98101
t.truthy(proxy.bucketsCache)
@@ -110,15 +113,10 @@ test('AssetProxy - initialize() with ALL_BUCKETS_IN_ACCOUNT mode throws on error
110113
try {
111114
process.env['ASSET_PROXY_BUCKET_OPTION'] = 'ALL_BUCKETS_IN_ACCOUNT'
112115

113-
const proxy = new AssetProxy()
116+
// Set up the mock to reject with an error
117+
s3Mock.on(ListBucketsCommand).rejects(new Error('Access denied'))
114118

115-
const mockS3Client = {
116-
send: async () => {
117-
throw new Error('Access denied')
118-
}
119-
}
120-
121-
proxy.getS3Client = () => mockS3Client
119+
const proxy = new AssetProxy()
122120

123121
await t.throwsAsync(
124122
async () => proxy.initialize(),
@@ -172,13 +170,11 @@ test('AssetProxy - isEnabled() returns true for ALL_BUCKETS_IN_ACCOUNT', async (
172170
try {
173171
process.env['ASSET_PROXY_BUCKET_OPTION'] = 'ALL_BUCKETS_IN_ACCOUNT'
174172

175-
const proxy = new AssetProxy()
176-
177-
const mockS3Client = {
178-
send: async () => ({ Buckets: [{ Name: 'bucket-1' }] })
179-
}
173+
s3Mock.on(ListBucketsCommand).resolves({
174+
Buckets: [{ Name: 'bucket-1' }]
175+
})
180176

181-
proxy.getS3Client = () => mockS3Client
177+
const proxy = new AssetProxy()
182178
await proxy.initialize()
183179

184180
t.true(proxy.isEnabled())
@@ -234,18 +230,14 @@ test('AssetProxy - shouldProxyBucket() with ALL_BUCKETS_IN_ACCOUNT mode only pro
234230
try {
235231
process.env['ASSET_PROXY_BUCKET_OPTION'] = 'ALL_BUCKETS_IN_ACCOUNT'
236232

237-
const proxy = new AssetProxy()
233+
s3Mock.on(ListBucketsCommand).resolves({
234+
Buckets: [
235+
{ Name: 'fetched-bucket-1' },
236+
{ Name: 'fetched-bucket-2' }
237+
]
238+
})
238239

239-
const mockS3Client = {
240-
send: async () => ({
241-
Buckets: [
242-
{ Name: 'fetched-bucket-1' },
243-
{ Name: 'fetched-bucket-2' }
244-
]
245-
})
246-
}
247-
248-
proxy.getS3Client = () => mockS3Client
240+
const proxy = new AssetProxy()
249241
await proxy.initialize()
250242

251243
t.true(proxy.shouldProxyBucket('fetched-bucket-1'))

0 commit comments

Comments
 (0)