Skip to content

Commit e77eaa4

Browse files
Merge pull request #507 from splitio/add-configs-endpoints
[SDK Configs] Separate configs endpoints from SDK endpoints
2 parents ad50b76 + 98c4b96 commit e77eaa4

11 files changed

Lines changed: 55 additions & 31 deletions

File tree

src/services/__tests__/splitApi.spec.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,25 @@ describe('splitApi', () => {
5050
assertHeaders(settings, headers);
5151
expect(url).toBe(expectedConfigsUrl(-1, 100, settings.validateFilters || false, settings));
5252

53+
splitApi.fetchConfigsSegmentChanges(-1, 'segmentName', false, 100);
54+
[url, { headers }] = fetchMock.mock.calls[5];
55+
assertHeaders(settings, headers);
56+
expect(url).toBe('configs/v1/segmentChanges/segmentName?since=-1&till=100');
57+
5358
splitApi.postEventsBulk('fake-body');
54-
assertHeaders(settings, fetchMock.mock.calls[5][1].headers);
59+
assertHeaders(settings, fetchMock.mock.calls[6][1].headers);
5560

5661
splitApi.postTestImpressionsBulk('fake-body');
57-
assertHeaders(settings, fetchMock.mock.calls[6][1].headers);
58-
expect(fetchMock.mock.calls[6][1].headers['SplitSDKImpressionsMode']).toBe(settings.sync.impressionsMode);
62+
assertHeaders(settings, fetchMock.mock.calls[7][1].headers);
63+
expect(fetchMock.mock.calls[7][1].headers['SplitSDKImpressionsMode']).toBe(settings.sync.impressionsMode);
5964

6065
splitApi.postTestImpressionsCount('fake-body');
61-
assertHeaders(settings, fetchMock.mock.calls[7][1].headers);
66+
assertHeaders(settings, fetchMock.mock.calls[8][1].headers);
6267

6368
splitApi.postMetricsConfig('fake-body');
64-
assertHeaders(settings, fetchMock.mock.calls[8][1].headers);
65-
splitApi.postMetricsUsage('fake-body');
6669
assertHeaders(settings, fetchMock.mock.calls[9][1].headers);
70+
splitApi.postMetricsUsage('fake-body');
71+
assertHeaders(settings, fetchMock.mock.calls[10][1].headers);
6772

6873
expect(telemetryTrackerMock.trackHttp).toBeCalledTimes(9);
6974

@@ -78,7 +83,7 @@ describe('splitApi', () => {
7883

7984
function expectedConfigsUrl(since: number, till: number, usesFilter: boolean, settings: ISettings) {
8085
const filterQueryString = settings.sync.__splitFiltersValidation && settings.sync.__splitFiltersValidation.queryString;
81-
return `sdk/v1/configs?since=${since}${usesFilter ? filterQueryString : ''}${till ? '&till=' + till : ''}`;
86+
return `configs/v1/configs?since=${since}${usesFilter ? filterQueryString : ''}${till ? '&till=' + till : ''}`;
8287
}
8388
});
8489

src/services/splitApi.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,20 @@ export function splitApiFactory(
6363
});
6464
},
6565

66+
fetchSegmentChanges(since: number, segmentName: string, noCache?: boolean, till?: number) {
67+
const url = `${urls.sdk}/segmentChanges/${segmentName}?since=${since}${till ? '&till=' + till : ''}`;
68+
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
69+
},
70+
6671
// @TODO support filterQueryString and handle ERROR_TOO_MANY_SETS error
6772
fetchConfigs(since: number, noCache?: boolean, till?: number) {
68-
const url = `${urls.sdk}/v1/configs?since=${since}${filterQueryString || ''}${till ? '&till=' + till : ''}`;
73+
const url = `${urls.configs}/v1/configs?since=${since}${filterQueryString || ''}${till ? '&till=' + till : ''}`;
6974
return (secureSplitHttpClient || splitHttpClient)(url, noCache ? noCacheHeaderOptions : undefined);
7075
},
7176

72-
fetchSegmentChanges(since: number, segmentName: string, noCache?: boolean, till?: number) {
73-
const url = `${urls.sdk}/segmentChanges/${segmentName}?since=${since}${till ? '&till=' + till : ''}`;
74-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
77+
fetchConfigsSegmentChanges(since: number, segmentName: string, noCache?: boolean, till?: number) {
78+
const url = `${urls.configs}/v1/segmentChanges/${segmentName}?since=${since}${till ? '&till=' + till : ''}`;
79+
return (secureSplitHttpClient || splitHttpClient)(url, noCache ? noCacheHeaderOptions : undefined);
7580
},
7681

7782
fetchMemberships(userMatchingKey: string, noCache?: boolean, till?: number) {

src/services/types.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,9 @@ export interface ISplitApi {
6262
getEventsAPIHealthCheck: IHealthCheckAPI
6363
fetchAuth: IFetchAuth
6464
fetchSplitChanges: IFetchDefinitionChanges
65-
fetchConfigs: IFetchDefinitionChanges
6665
fetchSegmentChanges: IFetchSegmentChanges
66+
fetchConfigs: IFetchDefinitionChanges
67+
fetchConfigsSegmentChanges: IFetchSegmentChanges
6768
fetchMemberships: IFetchMemberships
6869
postEventsBulk: IPostEventsBulk
6970
postUniqueKeysBulkCs: IPostUniqueKeysBulkCs

src/sync/polling/pollingManagerSS.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,22 @@ import { segmentsSyncTaskFactory } from './syncTasks/segmentsSyncTask';
33
import { IPollingManager, ISegmentsSyncTask, IDefinitionsSyncTask } from './types';
44
import { POLLING_START, POLLING_STOP, LOG_PREFIX_SYNC_POLLING } from '../../logger/constants';
55
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
6-
import { IDefinitionChangesFetcher } from './fetchers/types';
6+
import { IDefinitionChangesFetcher, ISegmentChangesFetcher } from './fetchers/types';
77

88
/**
99
* Expose start / stop mechanism for pulling data from services.
1010
*/
1111
export function pollingManagerSSFactory(
1212
params: ISdkFactoryContextSync,
13-
definitionChangesFetcher: IDefinitionChangesFetcher
13+
definitionChangesFetcher: IDefinitionChangesFetcher,
14+
segmentChangesFetcher: ISegmentChangesFetcher
1415
): IPollingManager {
1516

16-
const { splitApi, storage, readiness, settings } = params;
17+
const { storage, readiness, settings } = params;
1718
const log = settings.log;
1819

1920
const definitionsSyncTask: IDefinitionsSyncTask = definitionsSyncTaskFactory(definitionChangesFetcher, storage, readiness, settings);
20-
const segmentsSyncTask: ISegmentsSyncTask = segmentsSyncTaskFactory(splitApi.fetchSegmentChanges, storage, readiness, settings);
21+
const segmentsSyncTask: ISegmentsSyncTask = segmentsSyncTaskFactory(segmentChangesFetcher, storage, readiness, settings);
2122

2223
return {
2324
definitionsSyncTask,

src/sync/polling/syncTasks/segmentsSyncTask.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@ import { IStorageSync } from '../../../storages/types';
22
import { IReadinessManager } from '../../../readiness/types';
33
import { syncTaskFactory } from '../../syncTask';
44
import { ISegmentsSyncTask } from '../types';
5-
import { segmentChangesFetcherFactory } from '../fetchers/segmentChangesFetcher';
6-
import { IFetchSegmentChanges } from '../../../services/types';
75
import { ISettings } from '../../../types';
86
import { segmentChangesUpdaterFactory } from '../updaters/segmentChangesUpdater';
7+
import { ISegmentChangesFetcher } from '../fetchers/types';
98

109
/**
1110
* Creates a sync task that periodically executes a `segmentChangesUpdater` task
1211
*/
1312
export function segmentsSyncTaskFactory(
14-
fetchSegmentChanges: IFetchSegmentChanges,
13+
segmentChangesFetcher: ISegmentChangesFetcher,
1514
storage: IStorageSync,
1615
readiness: IReadinessManager,
1716
settings: ISettings,
@@ -20,7 +19,7 @@ export function segmentsSyncTaskFactory(
2019
settings.log,
2120
segmentChangesUpdaterFactory(
2221
settings.log,
23-
segmentChangesFetcherFactory(fetchSegmentChanges),
22+
segmentChangesFetcher,
2423
storage.segments,
2524
readiness,
2625
settings.startup.requestTimeoutBeforeReady,

src/sync/syncManagerOnline.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ import { ISdkFactoryContextSync } from '../sdkFactory/types';
1212
import { SDK_DEFINITIONS_CACHE_LOADED } from '../readiness/constants';
1313
import { usesSegmentsSync } from '../storages/AbstractDefinitionsCacheSync';
1414
import { splitChangesFetcherFactory } from './polling/fetchers/splitChangesFetcher';
15-
import { IDefinitionChangesFetcher } from './polling/fetchers/types';
15+
import { IDefinitionChangesFetcher, ISegmentChangesFetcher } from './polling/fetchers/types';
16+
import { segmentChangesFetcherFactory } from './polling/fetchers/segmentChangesFetcher';
1617

1718
/**
1819
* Online SyncManager factory.
@@ -24,9 +25,10 @@ import { IDefinitionChangesFetcher } from './polling/fetchers/types';
2425
* @param definitionChangesFetcherFactory - optional to replace the default split changes fetcher
2526
*/
2627
export function syncManagerOnlineFactory(
27-
pollingManagerFactory?: (params: ISdkFactoryContextSync, definitionChangesFetcher: IDefinitionChangesFetcher) => IPollingManager,
28+
pollingManagerFactory?: (params: ISdkFactoryContextSync, definitionChangesFetcher: IDefinitionChangesFetcher, segmentChangesFetcher: ISegmentChangesFetcher) => IPollingManager,
2829
pushManagerFactory?: (params: ISdkFactoryContextSync, pollingManager: IPollingManager) => IPushManager | undefined,
29-
definitionChangesFetcherFactory = splitChangesFetcherFactory
30+
definitionFetcherFactory = splitChangesFetcherFactory,
31+
segmentFetcherFactory = (params: ISdkFactoryContextSync) => segmentChangesFetcherFactory(params.splitApi.fetchSegmentChanges)
3032
): (params: ISdkFactoryContextSync) => ISyncManagerCS {
3133

3234
/**
@@ -37,15 +39,15 @@ export function syncManagerOnlineFactory(
3739
const { settings, settings: { log, streamingEnabled, sync: { enabled: syncEnabled } }, telemetryTracker, storage, readiness } = params;
3840

3941
/** Polling Manager */
40-
const pollingManager = pollingManagerFactory && pollingManagerFactory(params, definitionChangesFetcherFactory(params));
42+
const pollingManager = pollingManagerFactory && pollingManagerFactory(params, definitionFetcherFactory(params), segmentFetcherFactory(params));
4143

4244
/** Push Manager */
4345
const pushManager = syncEnabled && streamingEnabled && pollingManager && pushManagerFactory ?
4446
pushManagerFactory(params, pollingManager) :
4547
undefined;
4648

4749
/** Submitter Manager */
48-
// It is not inyected as push and polling managers, because at the moment it is required
50+
// It is not injected as push and polling managers, because at the moment it is required
4951
const submitterManager = submitterManagerFactory(params);
5052

5153
/** Sync Manager logic */

src/utils/settingsValidation/__tests__/index.spec.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ describe('settingsValidation', () => {
3838
auth: 'https://auth.split.io/api',
3939
streaming: 'https://streaming.split.io',
4040
telemetry: 'https://telemetry.split.io/api',
41+
configs: 'https://configs.split.io/api',
4142
});
4243
expect(settings.sync.impressionsMode).toBe(OPTIMIZED);
4344
expect(settings.sync.enabled).toBe(true);
@@ -82,6 +83,7 @@ describe('settingsValidation', () => {
8283
auth: 'auth-url',
8384
streaming: 'streaming-url',
8485
telemetry: 'telemetry-url',
86+
configs: 'configs-url',
8587
};
8688

8789
const settings = settingsValidation({

src/utils/settingsValidation/__tests__/settings.mocks.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ export const fullSettings: ISettings = {
8080
events: 'https://events.split.io/api',
8181
auth: 'https://auth.split.io/api',
8282
streaming: 'https://streaming.split.io',
83-
telemetry: 'https://telemetry.split.io/api'
83+
telemetry: 'https://telemetry.split.io/api',
84+
configs: 'https://configs.split.io/api'
8485
},
8586
log: loggerMock,
8687
userConsent: undefined
@@ -105,7 +106,8 @@ export const settingsSplitApi = {
105106
sdk: 'sdk',
106107
auth: 'auth',
107108
streaming: 'streaming',
108-
telemetry: 'telemetry'
109+
telemetry: 'telemetry',
110+
configs: 'configs'
109111
},
110112
sync: {
111113
impressionsMode: 'DEBUG',

src/utils/settingsValidation/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ export const base = {
5858
streaming: 'https://streaming.split.io',
5959
// Telemetry Server
6060
telemetry: 'https://telemetry.split.io/api',
61+
// Configs Server
62+
configs: 'https://configs.split.io/api',
6163
},
6264

6365
// Defines which kind of storage we should instantiate.

src/utils/settingsValidation/url.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { ISettings } from '../../types';
22

3-
const telemetryEndpointMatcher = /^\/v1\/metrics\/(config|usage)/;
3+
const telemetryEndpointMatcher = /^\/v1\/(metrics|keys)\/(config|usage|ss|cs)/;
44
const eventsEndpointMatcher = /^\/(testImpressions|metrics|events)/;
55
const authEndpointMatcher = /^\/(v2|v3)\/auth/;
66
const streamingEndpointMatcher = /^\/(sse|event-stream)/;
7+
const configsEndpointMatcher = /^\/v1\/(configs|segmentChanges)/;
78

89
/**
910
* Get URL based on a given target (path).
@@ -26,5 +27,8 @@ export function url(settings: ISettings, target: string) {
2627
if (streamingEndpointMatcher.test(target)) {
2728
return `${settings.urls.streaming}${target}`;
2829
}
30+
if (configsEndpointMatcher.test(target)) {
31+
return `${settings.urls.configs}${target}`;
32+
}
2933
return `${settings.urls.sdk}${target}`;
3034
}

0 commit comments

Comments
 (0)