Skip to content

Commit 53dbd10

Browse files
authored
feat(global-writes): setup feature support COMPASS-8273 (#6271)
* setup global writes support * fix tests
1 parent 2b8df72 commit 53dbd10

File tree

8 files changed

+163
-65
lines changed

8 files changed

+163
-65
lines changed

packages/compass-connections/src/hooks/use-connection-supports.spec.ts

+123-62
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ const mockConnections: ConnectionInfo[] = [
2323
metricsId: 'metricsId',
2424
metricsType: 'host',
2525
instanceSize: 'M10',
26+
clusterType: 'REPLICASET',
27+
clusterUniqueId: 'clusterUniqueId',
2628
},
2729
},
2830
{
@@ -38,6 +40,8 @@ const mockConnections: ConnectionInfo[] = [
3840
metricsId: 'metricsId',
3941
metricsType: 'replicaSet',
4042
instanceSize: 'M0',
43+
clusterType: 'REPLICASET',
44+
clusterUniqueId: 'clusterUniqueId',
4145
},
4246
},
4347
{
@@ -53,6 +57,8 @@ const mockConnections: ConnectionInfo[] = [
5357
metricsId: 'metricsId',
5458
metricsType: 'serverless',
5559
instanceSize: 'SERVERLESS_V2',
60+
clusterType: 'REPLICASET',
61+
clusterUniqueId: 'clusterUniqueId',
5662
},
5763
},
5864
{
@@ -68,6 +74,8 @@ const mockConnections: ConnectionInfo[] = [
6874
metricsId: 'metricsId',
6975
metricsType: 'replicaSet',
7076
instanceSize: 'M10',
77+
clusterType: 'REPLICASET',
78+
clusterUniqueId: 'clusterUniqueId',
7179
},
7280
},
7381
{
@@ -83,79 +91,132 @@ const mockConnections: ConnectionInfo[] = [
8391
metricsId: 'metricsId',
8492
metricsType: 'cluster',
8593
instanceSize: 'M10',
94+
clusterType: 'SHARDED',
95+
clusterUniqueId: 'clusterUniqueId',
96+
},
97+
},
98+
{
99+
id: 'dedicated-geo-sharded',
100+
connectionOptions: {
101+
connectionString: 'mongodb://foo',
102+
},
103+
atlasMetadata: {
104+
orgId: 'orgId',
105+
projectId: 'projectId',
106+
clusterName: 'clusterName',
107+
regionalBaseUrl: 'https://example.com',
108+
metricsId: 'metricsId',
109+
metricsType: 'cluster',
110+
instanceSize: 'M30',
111+
clusterType: 'GEOSHARDED',
112+
clusterUniqueId: 'clusterUniqueId',
86113
},
87114
},
88115
];
89116

90117
describe('useConnectionSupports', function () {
91-
it('should return false if the connection does not exist', function () {
92-
const { result } = renderHookWithConnections(
93-
() => useConnectionSupports('does-not-exist', 'rollingIndexCreation'),
94-
{
95-
connections: mockConnections,
96-
}
97-
);
98-
expect(result.current).to.equal(false);
99-
});
118+
context('rollingIndexCreation', function () {
119+
it('should return false if the connection does not exist', function () {
120+
const { result } = renderHookWithConnections(
121+
() => useConnectionSupports('does-not-exist', 'rollingIndexCreation'),
122+
{
123+
connections: mockConnections,
124+
}
125+
);
126+
expect(result.current).to.equal(false);
127+
});
100128

101-
it('should return false if the connection has no atlasMetadata', function () {
102-
const { result } = renderHookWithConnections(
103-
() => useConnectionSupports('no-atlasMetadata', 'rollingIndexCreation'),
104-
{
105-
connections: mockConnections,
106-
}
107-
);
108-
expect(result.current).to.equal(false);
109-
});
129+
it('should return false if the connection has no atlasMetadata', function () {
130+
const { result } = renderHookWithConnections(
131+
() => useConnectionSupports('no-atlasMetadata', 'rollingIndexCreation'),
132+
{
133+
connections: mockConnections,
134+
}
135+
);
136+
expect(result.current).to.equal(false);
137+
});
110138

111-
it('should return false for host cluster type', function () {
112-
const { result } = renderHookWithConnections(
113-
() => useConnectionSupports('host-cluster', 'rollingIndexCreation'),
114-
{
115-
connections: mockConnections,
116-
}
117-
);
118-
expect(result.current).to.equal(false);
119-
});
139+
it('should return false for host cluster type', function () {
140+
const { result } = renderHookWithConnections(
141+
() => useConnectionSupports('host-cluster', 'rollingIndexCreation'),
142+
{
143+
connections: mockConnections,
144+
}
145+
);
146+
expect(result.current).to.equal(false);
147+
});
120148

121-
it('should return false for serverless cluster type', function () {
122-
const { result } = renderHookWithConnections(
123-
() => useConnectionSupports('serverless-cluster', 'rollingIndexCreation'),
124-
{
125-
connections: mockConnections,
126-
}
127-
);
128-
expect(result.current).to.equal(false);
129-
});
149+
it('should return false for serverless cluster type', function () {
150+
const { result } = renderHookWithConnections(
151+
() =>
152+
useConnectionSupports('serverless-cluster', 'rollingIndexCreation'),
153+
{
154+
connections: mockConnections,
155+
}
156+
);
157+
expect(result.current).to.equal(false);
158+
});
130159

131-
it('should return false for free/shared tier clusters', function () {
132-
const { result } = renderHookWithConnections(
133-
() => useConnectionSupports('free-cluster', 'rollingIndexCreation'),
134-
{
135-
connections: mockConnections,
136-
}
137-
);
138-
expect(result.current).to.equal(false);
139-
});
160+
it('should return false for free/shared tier clusters', function () {
161+
const { result } = renderHookWithConnections(
162+
() => useConnectionSupports('free-cluster', 'rollingIndexCreation'),
163+
{
164+
connections: mockConnections,
165+
}
166+
);
167+
expect(result.current).to.equal(false);
168+
});
169+
170+
it('should return true for dedicated replicaSet clusters', function () {
171+
const { result } = renderHookWithConnections(
172+
() =>
173+
useConnectionSupports('dedicated-replicaSet', 'rollingIndexCreation'),
174+
{
175+
connections: mockConnections,
176+
}
177+
);
178+
expect(result.current).to.equal(true);
179+
});
140180

141-
it('should return true for dedicated replicaSet clusters', function () {
142-
const { result } = renderHookWithConnections(
143-
() =>
144-
useConnectionSupports('dedicated-replicaSet', 'rollingIndexCreation'),
145-
{
146-
connections: mockConnections,
147-
}
148-
);
149-
expect(result.current).to.equal(true);
181+
it('should return true for dedicated sharded clusters', function () {
182+
const { result } = renderHookWithConnections(
183+
() =>
184+
useConnectionSupports('dedicated-sharded', 'rollingIndexCreation'),
185+
{
186+
connections: mockConnections,
187+
}
188+
);
189+
expect(result.current).to.equal(true);
190+
});
150191
});
192+
context('globalWrites', function () {
193+
it('should return false if the connection does not exist', function () {
194+
const { result } = renderHookWithConnections(
195+
() => useConnectionSupports('does-not-exist', 'globalWrites'),
196+
{
197+
connections: mockConnections,
198+
}
199+
);
200+
expect(result.current).to.equal(false);
201+
});
202+
it('should return false if the connection has no atlasMetadata', function () {
203+
const { result } = renderHookWithConnections(
204+
() => useConnectionSupports('no-atlasMetadata', 'globalWrites'),
205+
{
206+
connections: mockConnections,
207+
}
208+
);
209+
expect(result.current).to.equal(false);
210+
});
151211

152-
it('should return true for dedicated sharded clusters', function () {
153-
const { result } = renderHookWithConnections(
154-
() => useConnectionSupports('dedicated-sharded', 'rollingIndexCreation'),
155-
{
156-
connections: mockConnections,
157-
}
158-
);
159-
expect(result.current).to.equal(true);
212+
it('should return true if the cluster type is geosharded', function () {
213+
const { result } = renderHookWithConnections(
214+
() => useConnectionSupports('dedicated-geo-sharded', 'globalWrites'),
215+
{
216+
connections: mockConnections,
217+
}
218+
);
219+
expect(result.current).to.equal(true);
220+
});
160221
});
161222
});

packages/compass-connections/src/hooks/use-connection-supports.ts

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { useSelector } from '../stores/store-context';
22
import type { ConnectionState } from '../stores/connections-store-redux';
33

4-
// only one for now
5-
type ConnectionFeature = 'rollingIndexCreation';
4+
type ConnectionFeature = 'rollingIndexCreation' | 'globalWrites';
65

76
function isFreeOrSharedTierCluster(instanceSize: string | undefined): boolean {
87
if (!instanceSize) {
@@ -25,6 +24,17 @@ function supportsRollingIndexCreation(connection: ConnectionState) {
2524
(metricsType === 'cluster' || metricsType === 'replicaSet')
2625
);
2726
}
27+
28+
function supportsGlobalWrites(connection: ConnectionState) {
29+
const atlasMetadata = connection.info?.atlasMetadata;
30+
31+
if (!atlasMetadata) {
32+
return false;
33+
}
34+
35+
return atlasMetadata.clusterType === 'GEOSHARDED';
36+
}
37+
2838
export function useConnectionSupports(
2939
connectionId: string,
3040
connectionFeature: ConnectionFeature
@@ -40,6 +50,10 @@ export function useConnectionSupports(
4050
return supportsRollingIndexCreation(connection);
4151
}
4252

53+
if (connectionFeature === 'globalWrites') {
54+
return supportsGlobalWrites(connection);
55+
}
56+
4357
return false;
4458
});
4559
}

packages/compass-preferences-model/src/preferences-schema.ts

+10
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ export type InternalUserPreferences = {
8787
telemetryAnonymousId?: string;
8888
telemetryAtlasUserId?: string;
8989
userCreatedAt: number;
90+
enableGlobalWrites: boolean;
9091
};
9192

9293
// UserPreferences contains all preferences stored to disk.
@@ -852,6 +853,15 @@ export const storedUserPreferencesProps: Required<{
852853
type: 'boolean',
853854
},
854855

856+
enableGlobalWrites: {
857+
ui: false,
858+
cli: false,
859+
global: false,
860+
description: null,
861+
validator: z.boolean().default(false),
862+
type: 'boolean',
863+
},
864+
855865
...allFeatureFlagsProps,
856866
};
857867

packages/compass-web/sandbox/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const App = () => {
5050
maximumNumberOfActiveConnections: isAtlas ? 10 : undefined,
5151
atlasServiceBackendPreset: atlasServiceSandboxBackendVariant,
5252
enableCreatingNewConnections: !isAtlas,
53+
enableGlobalWrites: isAtlas,
5354
}}
5455
onTrack={sandboxTelemetry.track}
5556
onDebug={sandboxLogger.debug}

packages/compass-web/src/connection-storage.spec.ts

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ describe('buildConnectionInfoFromClusterDescription', function () {
161161
metricsType: type === 'sharded' ? 'cluster' : type,
162162
instanceSize: expectedInstanceSize,
163163
regionalBaseUrl: 'https://example.com',
164+
clusterType: clusterDescription.clusterType,
164165
});
165166
});
166167
}

packages/compass-web/src/connection-storage.tsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ type ReplicationSpec = {
2525
regionConfigs: RegionConfig[];
2626
};
2727

28+
type ClusterType = 'REPLICASET' | 'SHARDED' | 'GEOSHARDED';
29+
2830
type ClusterDescription = {
2931
'@provider': string;
3032
uniqueId: string;
3133
groupId: string;
3234
name: string;
33-
clusterType: string;
35+
clusterType: ClusterType;
3436
srvAddress: string;
3537
state: string;
3638
deploymentItemName: string;
@@ -196,6 +198,7 @@ export function buildConnectionInfoFromClusterDescription(
196198
regionalBaseUrl: description.dataProcessingRegion.regionalUrl,
197199
...getMetricsIdAndType(description, deploymentItem),
198200
instanceSize: getInstanceSize(description),
201+
clusterType: description.clusterType,
199202
},
200203
};
201204
}

packages/compass-web/src/entrypoint.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ const CompassWeb = ({
274274
trackUsageStatistics: true,
275275
enableShell: false,
276276
enableCreatingNewConnections: false,
277+
enableGlobalWrites: false,
277278
...initialPreferences,
278279
})
279280
);

packages/connection-info/src/connection-info.ts

+7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ export interface AtlasClusterMetadata {
4949
* https://github.com/10gen/mms/blob/9e6bf2d81d4d85b5ac68a15bf471dcddc5922323/client/packages/types/nds/provider.ts#L60-L107
5050
*/
5151
instanceSize?: string;
52+
53+
/**
54+
* Possible types of Atlas clusters.
55+
* Copied from:
56+
* https://github.com/10gen/mms/blob/9e6bf2d81d4d85b5ac68a15bf471dcddc5922323/client/packages/types/nds/clusterDescription.ts#L12-L16
57+
*/
58+
clusterType: 'REPLICASET' | 'SHARDED' | 'GEOSHARDED';
5259
}
5360

5461
export interface ConnectionInfo {

0 commit comments

Comments
 (0)