Skip to content

Commit d515a41

Browse files
authored
fix(shell-api): fix prompt for Atlas-proxy-style mongos MONGOSH-680 (#797)
When connected to a server that we know is an Atlas server but announces itself as a mongos, print “atlas proxy” in the prompt rather than “mongos” to avoid confusion. As a drive-by fix, make sure to use the service provider of the current database, and not necessarily the initial one, as new connections can be assigned to `db`.
1 parent 7686fbb commit d515a41

File tree

4 files changed

+66
-5
lines changed

4 files changed

+66
-5
lines changed

packages/cli-repl/src/mongosh-repl.spec.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,5 +678,36 @@ describe('MongoshNodeRepl', () => {
678678
expect(output).to.contain('> ');
679679
expect(output).to.not.contain('error');
680680
});
681+
682+
it('changes the prompt when db is reassigned', async() => {
683+
const connectionInfo = {
684+
extraInfo: {
685+
uri: 'mongodb://localhost:27017/test',
686+
is_localhost: true
687+
},
688+
buildInfo: {
689+
version: '4.4.1',
690+
modules: ['enterprise']
691+
}
692+
};
693+
694+
sp.getConnectionInfo.resolves(connectionInfo);
695+
sp.getNewConnection.callsFake(async() => {
696+
Object.assign(connectionInfo.extraInfo, {
697+
is_localhost: true,
698+
is_data_lake: true
699+
});
700+
return sp;
701+
});
702+
sp.platform = 2; // ReplPlatform.CLI ... let's maybe stop using an enum for this
703+
704+
const initialized = await mongoshRepl.initialize(serviceProvider);
705+
await mongoshRepl.startRepl(initialized);
706+
expect(output).to.contain('Enterprise > ');
707+
708+
input.write('db = Mongo("foo").getDB("bar")\n');
709+
await waitEval(bus);
710+
expect(output).to.contain('Atlas Data Lake > ');
711+
});
681712
});
682713
});

packages/shell-api/src/mongo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ export default class Mongo extends ShellApiClass {
117117
// if used too early.
118118
get _serviceProvider(): ServiceProvider {
119119
if (this.__serviceProvider === null) {
120-
throw new MongoshInternalError('No ServiceProvider available for this mongo');
120+
throw new MongoshInternalError('No ServiceProvider available for this mongo', ShellApiErrors.NotConnected);
121121
}
122122
return this.__serviceProvider;
123123
}

packages/shell-api/src/shell-internal-state.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,26 @@ describe('ShellInternalState', () => {
249249
});
250250
});
251251

252+
describe('topology Sharded but it’s Atlas', () => {
253+
it('shows atlas proxy identifier', async() => {
254+
serviceProvider.getTopology.returns({
255+
description: {
256+
type: 'Sharded'
257+
}
258+
});
259+
serviceProvider.getConnectionInfo.resolves({
260+
extraInfo: {
261+
uri: 'mongodb://localhost/',
262+
is_atlas: true
263+
}
264+
});
265+
266+
await internalState.fetchConnectionInfo();
267+
const prompt = await internalState.getDefaultPrompt();
268+
expect(prompt).to.equal('[atlas proxy]> ');
269+
});
270+
});
271+
252272
describe('topology Unknown', () => {
253273
it('just shows the default prompt', async() => {
254274
const servers = new Map();

packages/shell-api/src/shell-internal-state.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,17 @@ export default class ShellInternalState {
236236
);
237237
}
238238

239+
get currentServiceProvider(): ServiceProvider {
240+
try {
241+
return this.currentDb._mongo._serviceProvider;
242+
} catch (err) {
243+
if (err.code === ShellApiErrors.NotConnected) {
244+
return this.initialServiceProvider;
245+
}
246+
throw err;
247+
}
248+
}
249+
239250
public emitApiCall(event: ApiEvent): void {
240251
this.messageBus.emit('mongosh:api-call', event);
241252
}
@@ -249,7 +260,7 @@ export default class ShellInternalState {
249260
// eslint-disable-next-line complexity
250261
topology: () => {
251262
let topology: Topologies;
252-
const topologyDescription = this.initialServiceProvider.getTopology()?.description as TopologyDescription;
263+
const topologyDescription = this.currentServiceProvider.getTopology()?.description as TopologyDescription;
253264
const topologyType: TopologyTypeId | undefined = topologyDescription?.type;
254265
switch (topologyType) {
255266
case 'ReplicaSetNoPrimary':
@@ -320,12 +331,11 @@ export default class ShellInternalState {
320331
}
321332

322333
private getTopologySpecificPrompt(): string {
323-
const description = this.initialServiceProvider.getTopology()?.description;
334+
const description = this.currentServiceProvider.getTopology()?.description;
324335
if (!description) {
325336
return '';
326337
}
327338

328-
329339
let replicaSet = description.setName;
330340
let serverTypePrompt = '';
331341
// TODO: replace with proper TopologyType constants - NODE-2973
@@ -342,7 +352,7 @@ export default class ShellInternalState {
342352
serverTypePrompt = '[primary]';
343353
break;
344354
case 'Sharded':
345-
serverTypePrompt = '[mongos]';
355+
serverTypePrompt = this.connectionInfo?.extraInfo?.is_atlas ? '[atlas proxy]' : '[mongos]';
346356
break;
347357
default:
348358
return '';

0 commit comments

Comments
 (0)