Skip to content

[#14123] feat(fileset): Support managed and external type conversion - #14124

Merged
jerryshao merged 5 commits into
apache:mainfrom
mchades:codex/fileset-type-conversion
Oct 23, 2026
Merged

jerryshao merged 5 commits into
apache:mainfrom
mchades:codex/fileset-type-conversion

Conversation

@mchades

@mchades mchades commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Add FilesetChange.updateType, Python update_type, and REST updateType support for changing existing filesets between MANAGED and EXTERNAL. Conversion preserves the fileset ID, locations, and files. Update the OpenAPI specification and usage documentation.

Also correct the quick-start wording that an existing path automatically makes a fileset external. This is a documentation correction; creation behavior is unchanged.

Why are the changes needed?

Users need to change an existing fileset's lifecycle ownership without dropping and recreating it. Converting to external allows its registration to be dropped while retaining the data; converting to managed explicitly accepts deletion on drop.

Related: #12550 and #13506.

Fix: #14123

Does this PR introduce any user-facing change?

Yes. A new fileset alter operation in Java, Python, and REST. Conversion does not move, create, or delete files; subsequent direct and schema-cascade drops use the updated type.

How was this patch tested?

  • 280 targeted Java tests passed: TestFilesetChange, TestFilesetUpdatesRequest, TestFilesetCatalog, TestFilesetOperations, and TestFilesetCatalogOperations with -PskipITs.
  • 3 Python tests passed: python -m unittest tests.unittests.test_fileset_type_change tests.unittests.test_fileset_catalog_api.
  • ./gradlew :docs:build, Spotless, Black, Pylint, and git diff --check passed.
  • Added coverage for both directions, preserved identity and data, multiple locations, repeated conversion, batched changes, direct drop, and schema cascade.

Docker integration tests were not run.

Copilot AI balanced review requested due to automatic review settings October 22, 2026 02:37

Copilot AI left a comment

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.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Copilot review overview

3 open issues
What changed in this PR

Adds a new “update fileset type” alter operation across Java, Python, and REST, enabling conversion between MANAGED and EXTERNAL without changing a fileset’s identity, locations, or existing files.

Changes:

  • Introduces FilesetChange.updateType / update_type and corresponding DTO/request plumbing for REST.
  • Implements catalog-side application of type changes and adds validation for invalid updateType requests.
  • Updates OpenAPI + docs and adds test coverage across server, API, catalog, and Python/Java clients.
File Description
server/​src/​test/​java/​org/​apache/​gravitino/​server/​web/​rest/​TestFilesetOperations.java Adds REST-layer tests for updateType and invalid request handling.
docs/​open-api/​filesets.yaml Extends OpenAPI schema with UpdateFilesetTypeRequest.
docs/​manage-fileset-metadata-using-gravitino.md Documents the new alter operation and provides examples.
docs/​filesets.md Updates lifecycle semantics wording and links to the new conversion operation.
common/​src/​test/​java/​org/​apache/​gravitino/​dto/​requests/​TestFilesetUpdatesRequest.java Adds serialization/validation tests for the new update request.
common/​src/​main/​java/​org/​apache/​gravitino/​dto/​requests/​FilesetUpdateRequest.java Adds UpdateFilesetTypeRequest DTO and validation.
clients/​client-python/​tests/​unittests/​test_fileset_type_change.py Adds unit tests for Python update_type and request validation.
clients/​client-python/​gravitino/​dto/​requests/​fileset_update_request.py Adds Python DTO for updateType.
clients/​client-python/​gravitino/​client/​fileset_catalog.py Maps FilesetChange.UpdateFilesetType to DTO requests.
clients/​client-python/​gravitino/​api/​file/​fileset_change.py Adds Python FilesetChange.update_type and UpdateFilesetType.
clients/​client-java/​src/​test/​java/​org/​apache/​gravitino/​client/​TestFilesetCatalog.java Adds client test for alterFileset with updateType change.
clients/​client-java/​src/​main/​java/​org/​apache/​gravitino/​client/​DTOConverters.java Converts FilesetChange.UpdateFilesetType to REST update request.
catalogs/​catalog-fileset/​src/​test/​java/​org/​apache/​gravitino/​catalog/​fileset/​TestFilesetCatalogOperations.java Adds integration-style tests for preservation semantics and drop behavior.
catalogs/​catalog-fileset/​src/​main/​java/​org/​apache/​gravitino/​catalog/​fileset/​FilesetCatalogOperations.java Applies UpdateFilesetType when updating persisted entity.
api/​src/​test/​java/​org/​apache/​gravitino/​file/​TestFilesetChange.java Adds API-level unit tests for FilesetChange.updateType.
api/​src/​main/​java/​org/​apache/​gravitino/​file/​FilesetChange.java Introduces updateType and UpdateFilesetType change type.

Review effort: Lite

Comment thread docs/filesets.md
Comment on lines +47 to +49
**2. Create the fileset.** Give it a name, a type, and a storage location. Choose `MANAGED` to let
Gravitino manage the data lifecycle, or `EXTERNAL` to retain the data when the fileset is dropped.
Pointing at an existing path does not automatically make a fileset external.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Creation behavior is unchanged. The previous quick-start wording incorrectly implied that an existing path makes a fileset external. I’ll clarify in the PR description that this is a documentation correction.

Comment on lines +26 to +29
/**
* A fileset change is a change to a fileset. It can be used to rename a fileset, update the comment
* of a fileset, set a property and value pair for a fileset, or remove a property from a fileset.
* or type of a fileset, set a property and value pair for a fileset, or remove a property from a
* fileset.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I’ve listed comment updates and type updates separately.

Comment on lines 27 to 30
class FilesetChange(ABC):
"""A fileset change is a change to a fileset. It can be used to rename a fileset, update the comment
of a fileset, set a property and value pair for a fileset, or remove a property from a fileset.
or type of a fileset, set a property and value pair for a fileset, or remove a property from a fileset.
"""

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I’ve listed the operations separately and kept the wording consistent with the Java API.

@jerryshao jerryshao left a comment

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.

Thanks for the PR. The conversion itself looks correct: id, locations and files are preserved, and subsequent drop / schema cascade follow the new type, including multi-location filesets. The main concern is authorization for EXTERNAL -> MANAGED (see inline comment; the auth check lives in FilesetOperations.java:290, outside the diff). A couple of doc clarifications and a Python nit as well.

newName = ((FilesetChange.RenameFileset) change).getNewName();
} else if (change instanceof FilesetChange.UpdateFilesetComment) {
newComment = ((FilesetChange.UpdateFilesetComment) change).getNewComment();
} else if (change instanceof FilesetChange.UpdateFilesetType) {

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.

updateType is authorized as a normal alterFileset (FILESET::OWNER or ANY_WRITE_FILESET, see FilesetOperations.java:290), while drop is owner-only. A principal with write but not drop can convert EXTERNAL to MANAGED and thereby make a later owner drop or schema cascade recursively delete every storage location. That is a new way for write to cause data loss. Please require the drop privilege for EXTERNAL to MANAGED, or document and test that write is intentionally enough to accept deletion.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I kept type conversion under the existing alterFileset authorization, consistent with WRITE_FILESET allowing data writes and metadata changes. I documented this and added an authorization test showing that a writer can convert both ways but still cannot drop the fileset.

Comment thread docs/filesets.md Outdated
A managed fileset belongs to Gravitino. Creating it creates the directory if needed, and deleting
it deletes the data.

An external fileset points at a location that already exists and stays under someone else's control.

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.

The quick-start correction is right: an existing path does not make a fileset external. The following sentence still says an external fileset points at a location that already exists. Create mkdirs for both types when the path is missing and adopts an existing directory for both. Please describe type as an explicit lifecycle flag, not as "directory already existed."

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I updated the definition of EXTERNAL to focus on data retention and clarified that either type creates a missing directory when filesystem operations are enabled.

its identifier, name, storage locations, properties, and existing files are preserved. Setting the
current type is allowed.

Change a `MANAGED` fileset to `EXTERNAL` before dropping it to retain its files. Changing an

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.

Conversion to MANAGED deletes locations on drop only when filesystem ops are enabled. With disable-filesystem-ops=true, drop still removes only metadata. Worth one sentence next to the new lifecycle text so "accepts deletion" is not read as unconditional.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I clarified that managed data deletion requires filesystem operations to be enabled. With disable-filesystem-ops=true, drop removes only metadata.

class UpdateFilesetType:
"""A fileset change to update the type without changing data or locations."""

_new_type: Fileset.Type = field(metadata=config(field_name="newType"))

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: UpdateFilesetType works, but please match the other change classes: snake_case field metadata on the change object (keep newType on the request DTO) and an explicit __eq__.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I switched the change object’s field metadata to new_type and added an explicit __eq__ to match the other change classes. The request DTO still uses newType.

@mchades
mchades requested a review from jerryshao October 22, 2026 14:03
@mchades mchades closed this Oct 22, 2026
@mchades mchades reopened this Oct 22, 2026
mchades added a commit to Ystk-hsn/gravitino that referenced this pull request Oct 23, 2026
…ntion

Validate all location filesystem states before creating directories. Preserve nested new locations and avoid leaving new directories when a later location is rejected.

Remove delete-data-on-drop in favor of the separate type-conversion work in apache#14124. Retain the creation guard and explicit adoption option, with regression coverage and updated documentation.
@jerryshao
jerryshao merged commit 2fe1b28 into apache:main Oct 23, 2026
4 checks passed
@mchades
mchades deleted the codex/fileset-type-conversion branch October 24, 2026 14:54
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.

[Improvement] Support changing filesets between managed and external

4 participants