Skip to content

Commit

Permalink
added filtering by enabled_in_oss to feature_environment store as well
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswk committed Nov 26, 2024
1 parent 999b395 commit f525028
Show file tree
Hide file tree
Showing 15 changed files with 99 additions and 76 deletions.
32 changes: 30 additions & 2 deletions src/lib/db/feature-environment-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import type {
FeatureEnvironmentKey,
IFeatureEnvironmentStore,
} from '../types/stores/feature-environment-store';
import type { Logger, LogProvider } from '../logger';
import type { Logger } from '../logger';
import metricsHelper from '../util/metrics-helper';
import { DB_TIME } from '../metric-events';
import type { IFeatureEnvironment, IVariant } from '../types/model';
import NotFoundError from '../error/notfound-error';
import { v4 as uuidv4 } from 'uuid';
import type { Db } from './db';
import type { IUnleashConfig } from '../types';

const T = {
featureEnvs: 'feature_environments',
Expand All @@ -36,14 +37,25 @@ export class FeatureEnvironmentStore implements IFeatureEnvironmentStore {

private readonly timer: Function;

constructor(db: Db, eventBus: EventEmitter, getLogger: LogProvider) {
private readonly isOss: boolean;
constructor(
db: Db,
eventBus: EventEmitter,
{
getLogger,
ui,
isEnterprise,
}: Pick<IUnleashConfig, 'getLogger' | 'ui' | 'isEnterprise'>,
) {
this.db = db;
this.logger = getLogger('feature-environment-store.ts');
this.timer = (action) =>
metricsHelper.wrapTimer(eventBus, DB_TIME, {
store: 'feature-environments',
action,
});
const isTest = process.env.NODE_ENV === 'test';
this.isOss = !isEnterprise && ui.environment !== 'pro' && !isTest;
}

async delete({
Expand Down Expand Up @@ -96,11 +108,26 @@ export class FeatureEnvironmentStore implements IFeatureEnvironmentStore {
);
}

addOssFilterIfNeeded(queryBuilder) {
if (this.isOss) {
return queryBuilder
.join(
'environments',
'environments.name',
'=',
`${T.featureEnvs}.environment`,
)
.where('environments.enabled_in_oss', true);
}
return queryBuilder;
}

async getAll(query?: Object): Promise<IFeatureEnvironment[]> {
let rows = this.db(T.featureEnvs);
if (query) {
rows = rows.where(query);
}
this.addOssFilterIfNeeded(rows);
return (await rows).map((r) => ({
enabled: r.enabled,
featureName: r.feature_name,
Expand All @@ -119,6 +146,7 @@ export class FeatureEnvironmentStore implements IFeatureEnvironmentStore {
if (environment) {
rows = rows.where({ environment });
}
this.addOssFilterIfNeeded(rows);
return (await rows).map((r) => ({
enabled: r.enabled,
featureName: r.feature_name,
Expand Down
12 changes: 3 additions & 9 deletions src/lib/db/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,7 @@ export const createStores = (
settingStore: new SettingStore(db, getLogger),
userStore: new UserStore(db, getLogger, config.flagResolver),
accountStore: new AccountStore(db, getLogger),
projectStore: new ProjectStore(
db,
eventBus,
getLogger,
config.flagResolver,
),
projectStore: new ProjectStore(db, eventBus, config),
tagStore: new TagStore(db, eventBus, getLogger),
tagTypeStore: new TagTypeStore(db, eventBus, getLogger),
addonStore: new AddonStore(db, eventBus, getLogger),
Expand All @@ -122,15 +117,14 @@ export const createStores = (
clientFeatureToggleStore: new FeatureToggleClientStore(
db,
eventBus,
getLogger,
config.flagResolver,
config,
),
environmentStore: new EnvironmentStore(db, eventBus, config),
featureTagStore: new FeatureTagStore(db, eventBus, getLogger),
featureEnvironmentStore: new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
config,
),
userSplashStore: new UserSplashStore(db, eventBus, getLogger),
roleStore: new RoleStore(db, eventBus, getLogger),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export class ClientFeatureToggleService {
this.logger = getLogger('services/client-feature-toggle-service.ts');
this.segmentReadModel = segmentReadModel;
this.clientFeatureToggleStore = clientFeatureToggleStore;
const isTest = process.env.NODE_ENV === 'test';
}

async getActiveSegmentsForClient() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Knex } from 'knex';
import metricsHelper from '../../util/metrics-helper';
import { DB_TIME } from '../../metric-events';
import type { Logger, LogProvider } from '../../logger';
import type { Logger } from '../../logger';
import type {
IFeatureToggleClient,
IFeatureToggleClientStore,
IFeatureToggleQuery,
IFlagResolver,
IStrategyConfig,
ITag,
IUnleashConfig,
PartialDeep,
} from '../../types';
import {
Expand Down Expand Up @@ -46,11 +47,20 @@ export default class FeatureToggleClientStore

private flagResolver: IFlagResolver;

private readonly isOss: boolean;

constructor(
db: Db,
eventBus: EventEmitter,
getLogger: LogProvider,
flagResolver: IFlagResolver,
{
getLogger,
flagResolver,
ui,
isEnterprise,
}: Pick<
IUnleashConfig,
'getLogger' | 'flagResolver' | 'ui' | 'isEnterprise'
>,
) {
this.db = db;
this.logger = getLogger('feature-toggle-client-store.ts');
Expand All @@ -60,6 +70,8 @@ export default class FeatureToggleClientStore
action,
});
this.flagResolver = flagResolver;
const isTest = process.env.NODE_ENV === 'test';
this.isOss = !isEnterprise && ui.environment !== 'pro' && !isTest;
}

private async getAll({
Expand All @@ -72,7 +84,7 @@ export default class FeatureToggleClientStore
const isPlayground = requestType === 'playground';
const environment = featureQuery?.environment || DEFAULT_ENV;
const stopTimer = this.timer(`getAllBy${requestType}`);

this.logger.info(`Getting all features and we're OSS: ${this.isOss}`);
let selectColumns = [
'features.name as name',
'features.description as description',
Expand Down Expand Up @@ -103,6 +115,10 @@ export default class FeatureToggleClientStore

let query = this.db('features')
.modify(FeatureToggleStore.filterByArchived, archived)
.modify(
FeatureToggleStore.filterByProjectsAccessibleByOss,
this.isOss,
)
.leftJoin(
this.db('feature_strategies')
.select('*')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,10 @@ export const createClientFeatureToggleService = (
db: Db,
config: IUnleashConfig,
): ClientFeatureToggleService => {
const { getLogger, eventBus, flagResolver } = config;

const featureToggleClientStore = new FeatureToggleClientStore(
db,
eventBus,
getLogger,
flagResolver,
config.eventBus,
config,
);

const segmentReadModel = new SegmentReadModel(db);
Expand All @@ -26,7 +23,7 @@ export const createClientFeatureToggleService = (
clientFeatureToggleStore: featureToggleClientStore,
},
segmentReadModel,
{ getLogger, flagResolver },
config,
);

return clientFeatureToggleService;
Expand All @@ -35,8 +32,6 @@ export const createClientFeatureToggleService = (
export const createFakeClientFeatureToggleService = (
config: IUnleashConfig,
): ClientFeatureToggleService => {
const { getLogger, flagResolver } = config;

const fakeClientFeatureToggleStore = new FakeClientFeatureToggleStore();

const fakeSegmentReadModel = new FakeSegmentReadModel();
Expand All @@ -46,7 +41,7 @@ export const createFakeClientFeatureToggleService = (
clientFeatureToggleStore: fakeClientFeatureToggleStore,
},
fakeSegmentReadModel,
{ getLogger, flagResolver },
config,
);

return clientFeatureToggleService;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,12 +150,7 @@ export const deferredExportImportTogglesService = (
);
const tagStore = new TagStore(db, eventBus, getLogger);
const tagTypeStore = new TagTypeStore(db, eventBus, getLogger);
const projectStore = new ProjectStore(
db,
eventBus,
getLogger,
flagResolver,
);
const projectStore = new ProjectStore(db, eventBus, config);
const featureTagStore = new FeatureTagStore(db, eventBus, getLogger);
const strategyStore = new StrategyStore(db, getLogger);
const contextFieldStore = new ContextFieldStore(
Expand All @@ -172,7 +167,7 @@ export const deferredExportImportTogglesService = (
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
config,
);
const eventStore = new EventStore(db, getLogger);
const accessService = createAccessService(db, config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const createFeatureLifecycleService =
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
config,
);
const eventService = createEventsService(db, config);
const featureLifecycleService = new FeatureLifecycleService(
Expand Down
12 changes: 3 additions & 9 deletions src/lib/features/feature-toggle/createFeatureToggleService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,13 @@ export const createFeatureToggleService = (
const featureToggleClientStore = new FeatureToggleClientStore(
db,
eventBus,
getLogger,
flagResolver,
);
const projectStore = new ProjectStore(
db,
eventBus,
getLogger,
flagResolver,
config,
);
const projectStore = new ProjectStore(db, eventBus, config);
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
config,
);
const contextFieldStore = new ContextFieldStore(
db,
Expand Down
10 changes: 10 additions & 0 deletions src/lib/features/feature-toggle/feature-toggle-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,16 @@ export default class FeatureToggleStore implements IFeatureToggleStore {
: queryBuilder.whereNull('archived_at');
};

static filterByProjectsAccessibleByOss: Knex.QueryCallbackWithArgs = (
queryBuilder: Knex.QueryBuilder,
isOss: boolean,
) => {
if (isOss) {
return queryBuilder.andWhere('project', '=', 'default');
}
return queryBuilder;
};

rowToFeature(row: FeaturesTable): FeatureToggle {
if (!row) {
throw new NotFoundError('No feature flag found');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,7 @@ export const createInstanceStatsService = (db: Db, config: IUnleashConfig) => {
flagResolver,
);
const userStore = new UserStore(db, getLogger, flagResolver);
const projectStore = new ProjectStore(
db,
eventBus,
getLogger,
flagResolver,
);
const projectStore = new ProjectStore(db, eventBus, config);
const environmentStore = new EnvironmentStore(db, eventBus, config);
const strategyStore = new StrategyStore(db, getLogger);
const contextFieldStore = new ContextFieldStore(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,9 @@ export const createEnvironmentService =
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
);
const projectStore = new ProjectStore(
db,
eventBus,
getLogger,
flagResolver,
config,
);
const projectStore = new ProjectStore(db, eventBus, config);
const featureStrategiesStore = new FeatureStrategiesStore(
db,
eventBus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ export const createProjectInsightsService = (
config: IUnleashConfig,
): ProjectInsightsService => {
const { eventBus, getLogger, flagResolver } = config;
const projectStore = new ProjectStore(
db,
eventBus,
getLogger,
flagResolver,
);
const projectStore = new ProjectStore(db, eventBus, config);
const featureToggleStore = new FeatureToggleStore(
db,
eventBus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,7 @@ export const createProjectStatusService = (
config: IUnleashConfig,
): ProjectStatusService => {
const eventStore = new EventStore(db, config.getLogger);
const projectStore = new ProjectStore(
db,
config.eventBus,
config.getLogger,
config.flagResolver,
);
const projectStore = new ProjectStore(db, config.eventBus, config);
const apiTokenStore = new ApiTokenStore(
db,
config.eventBus,
Expand Down
9 changes: 2 additions & 7 deletions src/lib/features/project/createProjectService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,7 @@ export const createProjectService = (
): ProjectService => {
const { eventBus, getLogger, flagResolver } = config;
const eventStore = new EventStore(db, getLogger);
const projectStore = new ProjectStore(
db,
eventBus,
getLogger,
flagResolver,
);
const projectStore = new ProjectStore(db, eventBus, config);
const projectOwnersReadModel = new ProjectOwnersReadModel(db);
const projectFlagCreatorsReadModel = new ProjectFlagCreatorsReadModel(db);
const groupStore = new GroupStore(db);
Expand All @@ -83,7 +78,7 @@ export const createProjectService = (
const featureEnvironmentStore = new FeatureEnvironmentStore(
db,
eventBus,
getLogger,
config,
);
const projectStatsStore = new ProjectStatsStore(db, eventBus, getLogger);
const accessService: AccessService = createAccessService(db, config);
Expand Down
Loading

0 comments on commit f525028

Please sign in to comment.