Skip to content

Commit 0dc18a5

Browse files
authored
refactor(regions): consolidate region-related functionality (#2782)
## Problem Anything related to regions is split between AwsContext and RegionProvider (plus some utility functions). But to do anything useful you usually needed both objects. ## Solution Move almost all region-related things to RegionProvider. This does make RegionProvider do a little bit more than I'd like though it's at least sticking to one idea.
1 parent ef1163a commit 0dc18a5

30 files changed

+508
-899
lines changed

src/apigateway/commands/copyUrl.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ import { ProgressLocation } from 'vscode'
1414

1515
import { Stage } from 'aws-sdk/clients/apigateway'
1616
import { DefaultApiGatewayClient } from '../../shared/clients/apiGatewayClient'
17-
import { RegionProvider } from '../../shared/regions/regionProvider'
18-
import { DEFAULT_DNS_SUFFIX } from '../../shared/regions/regionUtilities'
17+
import { DEFAULT_DNS_SUFFIX, RegionProvider } from '../../shared/regions/regionProvider'
1918
import { getLogger } from '../../shared/logger'
2019
import { recordApigatewayCopyUrl } from '../../shared/telemetry/telemetry'
2120

src/awsexplorer/activation.ts

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ import { LoginManager } from '../credentials/loginManager'
88
import { submitFeedback } from '../feedback/vue/submitFeedback'
99
import { deleteCloudFormation } from '../lambda/commands/deleteCloudFormation'
1010
import { CloudFormationStackNode } from '../lambda/explorer/cloudFormationNodes'
11-
import { AwsContext } from '../shared/awsContext'
12-
import { AwsContextTreeCollection } from '../shared/awsContextTreeCollection'
1311
import globals from '../shared/extensionGlobals'
1412
import { ExtContext } from '../shared/extensions'
1513
import { getLogger } from '../shared/logger'
@@ -33,7 +31,6 @@ import { createLocalExplorerView } from './localExplorer'
3331
*/
3432
export async function activate(args: {
3533
context: ExtContext
36-
awsContextTrees: AwsContextTreeCollection
3734
regionProvider: RegionProvider
3835
toolkitOutputChannel: vscode.OutputChannel
3936
remoteInvokeOutputChannel: vscode.OutputChannel
@@ -56,9 +53,22 @@ export async function activate(args: {
5653
})
5754
)
5855

59-
args.awsContextTrees.addTree(awsExplorer)
56+
recordVscodeActiveRegions({ value: args.regionProvider.getExplorerRegions().length })
6057

61-
updateAwsExplorerWhenAwsContextCredentialsChange(awsExplorer, args.context.awsContext, globals.context)
58+
args.context.extensionContext.subscriptions.push(
59+
args.context.awsContext.onDidChangeContext(async credentialsChangedEvent => {
60+
getLogger().verbose(`Credentials changed (${credentialsChangedEvent.profileName}), updating AWS Explorer`)
61+
awsExplorer.refresh()
62+
63+
if (credentialsChangedEvent.profileName) {
64+
await checkExplorerForDefaultRegion(
65+
credentialsChangedEvent.profileName,
66+
args.regionProvider,
67+
awsExplorer
68+
)
69+
}
70+
})
71+
)
6272
}
6373

6474
async function registerAwsExplorerCommands(
@@ -125,20 +135,3 @@ async function registerAwsExplorerCommands(
125135
const developerTools = createLocalExplorerView()
126136
context.extensionContext.subscriptions.push(developerTools)
127137
}
128-
129-
function updateAwsExplorerWhenAwsContextCredentialsChange(
130-
awsExplorer: AwsExplorer,
131-
awsContext: AwsContext,
132-
extensionContext: vscode.ExtensionContext
133-
) {
134-
extensionContext.subscriptions.push(
135-
awsContext.onDidChangeContext(async credentialsChangedEvent => {
136-
getLogger().verbose(`Credentials changed (${credentialsChangedEvent.profileName}), updating AWS Explorer`)
137-
awsExplorer.refresh()
138-
139-
if (credentialsChangedEvent.profileName) {
140-
await checkExplorerForDefaultRegion(credentialsChangedEvent.profileName, awsContext, awsExplorer)
141-
}
142-
})
143-
)
144-
}

src/awsexplorer/awsExplorer.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import { AwsContext } from '../shared/awsContext'
88
import { getIdeProperties } from '../shared/extensionUtilities'
99
import { getLogger, Logger } from '../shared/logger'
1010
import { RegionProvider } from '../shared/regions/regionProvider'
11-
import { getRegionsForActiveCredentials } from '../shared/regions/regionUtilities'
1211
import { RefreshableAwsTreeProvider } from '../shared/treeview/awsTreeProvider'
1312
import { AWSCommandTreeNode } from '../shared/treeview/nodes/awsCommandTreeNode'
1413
import { AWSTreeNodeBase } from '../shared/treeview/nodes/awsTreeNodeBase'
@@ -69,7 +68,7 @@ export class AwsExplorer implements vscode.TreeDataProvider<AWSTreeNodeBase>, Re
6968
})
7069
)
7170
this.extContext.subscriptions.push(
72-
this.regionProvider.onRegionProviderUpdated(() => {
71+
this.regionProvider.onDidChange(() => {
7372
this.logger.verbose('Refreshing AWS Explorer due to Region Provider updates')
7473
this.refresh()
7574
})
@@ -82,7 +81,7 @@ export class AwsExplorer implements vscode.TreeDataProvider<AWSTreeNodeBase>, Re
8281

8382
public async getChildren(element?: AWSTreeNodeBase): Promise<AWSTreeNodeBase[]> {
8483
if (element) {
85-
this.awsContext.setLastTouchedRegion(element.regionCode)
84+
this.regionProvider.setLastTouchedRegion(element.regionCode)
8685
}
8786

8887
let childNodes: AWSTreeNodeBase[] = []
@@ -126,9 +125,8 @@ export class AwsExplorer implements vscode.TreeDataProvider<AWSTreeNodeBase>, Re
126125
return [this.ROOT_NODE_SIGN_IN]
127126
}
128127

129-
const partitionRegions = getRegionsForActiveCredentials(this.awsContext, this.regionProvider)
130-
131-
const userVisibleRegionCodes = await this.awsContext.getExplorerRegions()
128+
const partitionRegions = this.regionProvider.getRegions()
129+
const userVisibleRegionCodes = this.regionProvider.getExplorerRegions()
132130
const regionMap = toMap(partitionRegions, r => r.id)
133131

134132
return await makeChildrenNodes({

src/awsexplorer/defaultRegion.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import * as nls from 'vscode-nls'
77
const localize = nls.loadMessageBundle()
88

99
import * as vscode from 'vscode'
10-
import { AwsContext } from '../shared/awsContext'
1110
import * as localizedText from '../shared/localizedText'
1211
import { createQuickPick, promptUser } from '../shared/ui/picker'
1312
import { AwsExplorer } from './awsExplorer'
1413
import { getIdeProperties, isCloud9 } from '../shared/extensionUtilities'
1514
import { PromptSettings } from '../shared/settings'
15+
import { RegionProvider } from '../shared/regions/regionProvider'
1616

1717
class RegionMissingUI {
1818
public static readonly add: string = localizedText.yes
@@ -25,18 +25,18 @@ class RegionMissingUI {
2525

2626
export async function checkExplorerForDefaultRegion(
2727
profileName: string,
28-
awsContext: AwsContext,
28+
regionProvider: RegionProvider,
2929
awsExplorer: AwsExplorer
3030
): Promise<void> {
31-
const profileRegion = awsContext.getCredentialDefaultRegion()
31+
const profileRegion = regionProvider.defaultRegionId
3232

33-
const explorerRegions = new Set(await awsContext.getExplorerRegions())
33+
const explorerRegions = new Set(regionProvider.getExplorerRegions())
3434
if (explorerRegions.has(profileRegion)) {
3535
return
3636
}
3737

3838
if (isCloud9()) {
39-
await awsContext.addExplorerRegion(profileRegion)
39+
await regionProvider.updateExplorerRegions([...explorerRegions, profileRegion])
4040
awsExplorer.refresh()
4141
return
4242
}
@@ -80,7 +80,7 @@ export async function checkExplorerForDefaultRegion(
8080
const response = r[0].label
8181

8282
if (response === RegionMissingUI.add) {
83-
await awsContext.addExplorerRegion(profileRegion)
83+
await regionProvider.updateExplorerRegions([...explorerRegions, profileRegion])
8484
awsExplorer.refresh()
8585
} else if (response === RegionMissingUI.alwaysIgnore) {
8686
PromptSettings.instance.disablePrompt('regionAddAutomatically')

src/awsexplorer/regionNode.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,9 @@ import { IotNode } from '../iot/explorer/iotNodes'
1515
import { EcsNode } from '../ecs/explorer/ecsNode'
1616
import { isCloud9 } from '../shared/extensionUtilities'
1717
import { Region } from '../shared/regions/endpoints'
18-
import { RegionProvider } from '../shared/regions/regionProvider'
18+
import { DEFAULT_PARTITION, RegionProvider } from '../shared/regions/regionProvider'
1919
import { AWSTreeNodeBase } from '../shared/treeview/nodes/awsTreeNodeBase'
2020
import { StepFunctionsNode } from '../stepFunctions/explorer/stepFunctionsNodes'
21-
import { DEFAULT_PARTITION } from '../shared/regions/regionUtilities'
2221
import { SsmDocumentNode } from '../ssmDocument/explorer/ssmDocumentNode'
2322
import { ResourcesNode } from '../dynamicResources/explorer/nodes/resourcesNode'
2423
import { AppRunnerNode } from '../apprunner/explorer/apprunnerNode'

src/credentials/loginManager.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import {
1717
CredentialType,
1818
recordAwsRefreshCredentials,
1919
recordAwsValidateCredentials,
20-
recordVscodeActiveRegions,
2120
Result,
2221
} from '../shared/telemetry/telemetry'
2322
import { CredentialsStore } from './credentialsStore'
@@ -76,7 +75,6 @@ export class LoginManager {
7675
if (!accountId) {
7776
throw new Error('Could not determine Account Id for credentials')
7877
}
79-
recordVscodeActiveRegions({ value: (await this.awsContext.getExplorerRegions()).length })
8078

8179
this.awsContext.credentialsShim = createCredentialsShim(this.store, args.providerId, credentials)
8280
await this.awsContext.setCredentials({

src/extension.ts

Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { SharedCredentialsProviderFactory } from './credentials/providers/shared
1616
import { activate as activateSchemas } from './eventSchemas/activation'
1717
import { activate as activateLambda } from './lambda/activation'
1818
import { DefaultAWSClientBuilder } from './shared/awsClientBuilder'
19-
import { AwsContextTreeCollection } from './shared/awsContextTreeCollection'
2019
import { activate as activateCloudFormationTemplateRegistry } from './shared/cloudformation/activation'
2120
import { documentationUrl, endpointsFileUrl, githubCreateIssueUrl, githubUrl } from './shared/constants'
2221
import { DefaultAwsContext } from './shared/awsContext'
@@ -32,7 +31,7 @@ import {
3231
} from './shared/extensionUtilities'
3332
import { getLogger, Logger } from './shared/logger/logger'
3433
import { activate as activateLogger } from './shared/logger/activation'
35-
import { DefaultRegionProvider } from './shared/regions/defaultRegionProvider'
34+
import { RegionProvider } from './shared/regions/regionProvider'
3635
import { EndpointsProvider } from './shared/regions/endpointsProvider'
3736
import { FileResourceFetcher } from './shared/resourcefetcher/fileResourceFetcher'
3837
import { HttpResourceFetcher } from './shared/resourcefetcher/httpResourceFetcher'
@@ -96,10 +95,9 @@ export async function activate(context: vscode.ExtensionContext) {
9695

9796
const endpointsProvider = makeEndpointsProvider()
9897

99-
const awsContext = new DefaultAwsContext(context)
98+
const awsContext = new DefaultAwsContext()
10099
globals.awsContext = awsContext
101-
const awsContextTrees = new AwsContextTreeCollection()
102-
const regionProvider = new DefaultRegionProvider(endpointsProvider)
100+
const regionProvider = RegionProvider.fromEndpointsProvider(endpointsProvider)
103101
const credentialsStore = new CredentialsStore()
104102
const loginManager = new LoginManager(awsContext, credentialsStore)
105103

@@ -112,7 +110,7 @@ export async function activate(context: vscode.ExtensionContext) {
112110

113111
await initializeAwsCredentialsStatusBarItem(awsContext, context)
114112
globals.regionProvider = regionProvider
115-
globals.awsContextCommands = new AwsContextCommands(awsContext, awsContextTrees, regionProvider, loginManager)
113+
globals.awsContextCommands = new AwsContextCommands(regionProvider, loginManager)
116114
globals.sdkClientBuilder = new DefaultAWSClientBuilder(awsContext)
117115
globals.schemaService = new SchemaService(context)
118116
globals.resourceManager = new AwsResourceManager(context)
@@ -190,7 +188,6 @@ export async function activate(context: vscode.ExtensionContext) {
190188

191189
await activateAwsExplorer({
192190
context: extContext,
193-
awsContextTrees,
194191
regionProvider,
195192
toolkitOutputChannel,
196193
remoteInvokeOutputChannel,
@@ -301,28 +298,6 @@ function makeEndpointsProvider(): EndpointsProvider {
301298
const remoteManifestFetcher = new HttpResourceFetcher(endpointsFileUrl, { showUrl: true })
302299

303300
const provider = new EndpointsProvider(localManifestFetcher, remoteManifestFetcher)
304-
// Start the load without waiting. It raises events as fetchers retrieve data.
305-
provider.load().catch((err: Error) => {
306-
getLogger().error('Failure while loading Endpoints Manifest: %O', err)
307-
308-
vscode.window.showErrorMessage(
309-
`${localize(
310-
'AWS.error.endpoint.load.failure',
311-
'The {0} Toolkit was unable to load endpoints data.',
312-
getIdeProperties().company
313-
)} ${
314-
isCloud9()
315-
? localize(
316-
'AWS.error.impactedFunctionalityReset.cloud9',
317-
'Toolkit functionality may be impacted until the Cloud9 browser tab is refreshed.'
318-
)
319-
: localize(
320-
'AWS.error.impactedFunctionalityReset.vscode',
321-
'Toolkit functionality may be impacted until VS Code is restarted.'
322-
)
323-
}`
324-
)
325-
})
326301

327302
return provider
328303
}

src/lambda/commands/createNewSamApp.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ import { getIdeProperties, isCloud9 } from '../../shared/extensionUtilities'
4646
import { execSync } from 'child_process'
4747
import { writeFile } from 'fs-extra'
4848
import { checklogs } from '../../shared/localizedText'
49-
import { getRegionsForActiveCredentials } from '../../shared/regions/regionUtilities'
5049
import globals from '../../shared/extensionGlobals'
5150

5251
type CreateReason = 'unknown' | 'userCancelled' | 'fileNotFound' | 'complete' | 'error'
@@ -147,9 +146,7 @@ export async function createNewSamApplication(
147146

148147
const credentials = await awsContext.getCredentials()
149148
samVersion = await getSamCliVersion(samCliContext)
150-
const schemaRegions = getRegionsForActiveCredentials(awsContext, regionProvider).filter(r =>
151-
regionProvider.isServiceInRegion('schemas', r.id)
152-
)
149+
const schemaRegions = regionProvider.getRegions().filter(r => regionProvider.isServiceInRegion('schemas', r.id))
153150
const defaultRegion = awsContext.getCredentialDefaultRegion()
154151

155152
const config = await new CreateNewSamAppWizard({

src/lambda/commands/deploySamApplication.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as vscode from 'vscode'
88
import * as nls from 'vscode-nls'
99

1010
import { asEnvironmentVariables } from '../../credentials/credentialsUtilities'
11-
import { AwsContext, NoActiveCredentialError } from '../../shared/awsContext'
11+
import { AwsContext } from '../../shared/awsContext'
1212
import globals from '../../shared/extensionGlobals'
1313

1414
import { makeTemporaryToolkitFolder, tryRemoveFolder } from '../../shared/filesystemUtilities'
@@ -73,7 +73,7 @@ export async function deploySamApplication(
7373
try {
7474
const credentials = await awsContext.getCredentials()
7575
if (!credentials) {
76-
throw new NoActiveCredentialError()
76+
throw new Error('No AWS profile selected')
7777
}
7878

7979
throwAndNotifyIfInvalid(await samCliContext.validator.detectValidSamCli())

src/lambda/wizards/samDeployWizard.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import * as vscode from 'vscode'
1313
import { samDeployDocUrl } from '../../shared/constants'
1414
import * as localizedText from '../../shared/localizedText'
1515
import { getLogger } from '../../shared/logger'
16-
import { getRegionsForActiveCredentials } from '../../shared/regions/regionUtilities'
1716
import { createHelpButton } from '../../shared/ui/buttons'
1817
import * as input from '../../shared/ui/input'
1918
import * as picker from '../../shared/ui/picker'
@@ -351,10 +350,7 @@ export class DefaultSamDeployWizardContext implements SamDeployWizardContext {
351350
}
352351

353352
public async promptUserForRegion(step: number, initialRegionCode?: string): Promise<string | undefined> {
354-
const partitionRegions = getRegionsForActiveCredentials(
355-
this.extContext.awsContext,
356-
this.extContext.regionProvider
357-
)
353+
const partitionRegions = this.extContext.regionProvider.getRegions()
358354

359355
const quickPick = picker.createQuickPick<vscode.QuickPickItem>({
360356
options: {

0 commit comments

Comments
 (0)