Skip to content

Add self-service overrides to table feature toggles - #666

Merged
cbb330 merged 1 commit into
linkedin:mainfrom
cbb330:chbush/table-feature-override-gate
Jul 31, 2026
Merged

Add self-service overrides to table feature toggles#666
cbb330 merged 1 commit into
linkedin:mainfrom
cbb330:chbush/table-feature-override-gate

Conversation

@cbb330

@cbb330 cbb330 commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

Problem: I have a feature which I want to ramp on the server. but I also don't want to prevent table owners from self-serve opting in. A generic function to handle that overlap doesn't exist today.

Extend the existing TableFeatureToggle with self-service table overrides while preserving its server-managed targeting API.

An explicit <featureId>.enabled=true|false table property wins. When the property is absent, activation delegates to the server toggle. Server rules now support trailing-* prefix matching independently for database and table names.

Changes

  • Client-facing API Changes
  • Internal API Changes
  • Bug Fixes
  • New Features
  • Performance Improvements
  • Code Style
  • Refactoring
  • Documentation
  • Tests

Adds a binary-compatible default method to TableFeatureToggle:

isFeatureActivatedWithOverride(TableDto tableDto, String featureId)

It is deliberately not an overload of isFeatureActivated. The two carry different safety contracts, and a distinct name makes the difference visible at the call site: authorization gates such as enable_mor decide whether a user may write a preserved table property, so they must keep using the server-only isFeatureActivated(String, String, String). The override-honoring form reads a property the gated user can write.

An override that is neither true nor false fails closed: it is logged and the feature is treated as inactive. The gate is evaluated on the table-load path, so throwing would turn a typo like read-bridge.enabled=flase into a 400 and make the table unloadable.

Extends the existing toggle rule matcher while preserving exact and * matching:

  • tracking.events matches exactly.
  • tracking_*.events_* matches database and table prefixes.
  • *.* matches every table.

Testing Done

  • Manually Tested on local docker setup. Please include commands ran, and their output.
  • Added new tests for the changes made.
  • Updated existing tests to reflect the changes made.
  • No tests added or updated. Please explain why. If unsure, please feel free to ask for help.
  • Some other form of testing like staging or soak time in production. Please explain.

Ran:

JAVA_HOME=$(/usr/libexec/java_home -v 17) ./gradlew \
  :services:tables:test \
  --tests 'com.linkedin.openhouse.tables.toggle.TableFeatureToggleTest' \
  :services:housetables:test \
  --tests 'com.linkedin.openhouse.housetables.mock.WildcardTableToggleRuleMatcherTest' \
  -x CopyGitHooksTask

All 12 focused tests passed, covering server fallback, explicit opt-in and opt-out, fail-closed handling of unparseable overrides, exact matching, wildcard matching, and paired database/table prefix matching.

Additional Information

  • Breaking Changes
  • Deprecations
  • Large PR broken into smaller PRs, and PR plan linked in the description.

This is an independent OSS foundation for the read-bridge stack in #645 and the corresponding li-openhouse implementation PRs. Feature-specific default derivation remains outside this PR.

Note for reviewers: the matcher change widens any existing table_toggle_rule row whose pattern ends in * but is not exactly *. Those previously matched nothing. Worth auditing HTS before merge.

@cbb330
cbb330 force-pushed the chbush/table-feature-override-gate branch 2 times, most recently from 88032e8 to f17ae1f Compare July 31, 2026 04:34
@cbb330 cbb330 changed the title Add generic table feature activation gate Add self-service overrides to table feature toggles Jul 31, 2026
@cbb330
cbb330 force-pushed the chbush/table-feature-override-gate branch 6 times, most recently from bc4547b to f16b5f7 Compare July 31, 2026 05:09
@cbb330
cbb330 marked this pull request as ready for review July 31, 2026 05:16
@cbb330
cbb330 force-pushed the chbush/table-feature-override-gate branch from f16b5f7 to dd7cb47 Compare July 31, 2026 17:23
@cbb330
cbb330 force-pushed the chbush/table-feature-override-gate branch from dd7cb47 to fa28104 Compare July 31, 2026 20:26

@kamanavishnu kamanavishnu left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed after the latest commit. All three open threads are resolved:

  • Wildcard matching now uses Spring AntPathMatcher, fixing the mid-pattern * fallback and adding a pinning test.
  • Case-sensitivity is intentionally preserved (consistent with pre-existing behavior and HTS key matching), with a test locking it in.
  • The authorization-gate safeguard is javadoc-only today; agreed this is fine for now given the proposed typed TableFeature.capability() vs .rollout() follow-up.

LGTM.

@cbb330
cbb330 merged commit d2451f7 into linkedin:main Jul 31, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants