Skip to content

feat(labels): Add labels for polaris entities#4146

Open
vignesh-manel wants to merge 6 commits intoapache:mainfrom
vignesh-manel:feature/labels
Open

feat(labels): Add labels for polaris entities#4146
vignesh-manel wants to merge 6 commits intoapache:mainfrom
vignesh-manel:feature/labels

Conversation

@vignesh-manel
Copy link
Copy Markdown

@vignesh-manel vignesh-manel commented Apr 8, 2026

Add key-value label support to Catalog entities for organizing and filtering catalogs via the management REST API.

  • Catalogs can now have optional key-value labels (e.g. env:prod, team:platform) set at creation or updated later
  • Labels are returned in catalog responses and omitted entirely when not set
  • UpdateCatalogRequest supports labels (replace) and clearLabels (remove all); the two are mutually exclusive
  • When labels is omitted on update, existing labels are preserved (non-destructive by default)
  • Validation enforces: key ≤ 128 chars, value ≤ 256 chars, max 20 labels per catalog

Checklist

  • 🛡️ Don't disclose security issues! (contact security@apache.org)
  • 🔗 Clearly explained why the changes are needed, or linked related issues: Fixes #
  • 🧪 Added/updated tests with good coverage, or manually tested (and explained how)
  • 💡 Added comments for complex logic
  • 🧾 Updated CHANGELOG.md (if needed)
  • 📚 Updated documentation in site/content/in-dev/unreleased (if needed)

@github-project-automation github-project-automation bot moved this to PRs In Progress in Basic Kanban Board Apr 8, 2026
@vignesh-manel vignesh-manel marked this pull request as ready for review April 8, 2026 17:20
@snazy
Copy link
Copy Markdown
Member

snazy commented Apr 9, 2026

Hi @vignesh-manel !

Thanks a lot for this! I took a brief look over the PR and I do not see anything that's technically worrisome. Sure, there are a few things, but those can be sorted out w/o a lot of hassle.

As this is a new feature, I just wonder whether it's better to go on the dev-mailing-list and start a discussion about this new feature to gather the community's opinion and eventually consensus. WDYT?

Robert

@vignesh-manel
Copy link
Copy Markdown
Author

Hi @vignesh-manel !

Thanks a lot for this! I took a brief look over the PR and I do not see anything that's technically worrisome. Sure, there are a few things, but those can be sorted out w/o a lot of hassle.

As this is a new feature, I just wonder whether it's better to go on the dev-mailing-list and start a discussion about this new feature to gather the community's opinion and eventually consensus. WDYT?

Robert

@snazy Thanks for taking a look, I have posted it in dev mail thread: https://lists.apache.org/thread/2ny3gx01dx85b3bzo58zkbddryrjhfr3

Copy link
Copy Markdown
Contributor

@dimas-b dimas-b left a comment

Choose a reason for hiding this comment

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

The feature LGTM at high level 👍 ... posting a couple of preliminary comments.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@vignesh-manel : If I may suggest moving CLI changes to a separate PR, I think it would simplify review (just different audiences usually review core and CLI changes).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thanks for the review.
Removed the CLI changes from this PR, will create a different PR for CLI, once this is merged.

$ref: "#/components/schemas/StorageConfigInfo"
labels:
type: object
x-extra-annotation: "@com.fasterxml.jackson.annotation.JsonInclude(com.fasterxml.jackson.annotation.JsonInclude.Include.NON_EMPTY)"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I believe it is preferable to keep the OpenAPI definition language-neutral.

I believe null values are already not included. Could we represent empty labels as null here?

Alternatively, it might be a good idea to make a separate change to avoid serializing empty values across all endpoints (cf. #1955, https://lists.apache.org/thread/nfboq6yo01x3lw4t3d5gp78f6lgs5ddz).

WDYT?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

removed this, now the response will have labels as empty map {} , similar to other collection type attributes in the APIs

// Update with labels omitted (null) — existing labels must be preserved
try (Response response =
managementApi
.request("v1/catalogs/{name}", Map.of("name", catalogName))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: maybe add a helper method to ManagementApi?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

added helper method updateCatalogLabels


// Filter by env=prod — only prodCatalog should match
try (Response response =
managementApi.request("v1/catalogs", Map.of(), Map.of("labelFilter", "env=prod")).get()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: new helper method in ManagementApi?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

added helper method listCatalogsByLabel

public static final String EMPTY_MAP_STRING = "{}";

/** Internal-property key under which entity labels are stored as a serialized JSON map. */
public static final String LABELS_INTERNAL_KEY = "polaris.entity.labels";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

protected seems sufficient... Let's not expand the public API surface in "core" unless really necessary.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

updated to protected

*/
@JsonIgnore
public Map<String, String> getLabels() {
String raw = getInternalPropertiesAsMap().get(LABELS_INTERNAL_KEY);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WDYT about modelling each label as a separate internal property? e.g. polaris.entity.label.env=dev?

* matches every entity.
*/
@JsonIgnore
public boolean matchesLabelFilter(@Nonnull Map<String, String> labelFilter) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: how about containsAllLabels? I think it would represent actual behaviour better.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

renamed to containsAllLabels

operationId: listCatalogs
description: List all catalogs in this polaris service
parameters:
- name: labelFilter
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

suggestion: rename to label and use : as the separator. A sample query could be curl -X GET http://.../catalogs?label=env:prod&label=team:eng... I reads nicer from my POV.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

thanks for this suggestion, this is better way, updated the code accordingly

}
Map<String, String> result = new HashMap<>(labelFilter.size());
for (String entry : labelFilter) {
int idx = entry.indexOf('=');
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We never actually process a label's key/value parts individually, right? Do we need to parse it at all?

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.

3 participants