This is an automated email from the ASF dual-hosted git repository.
fanng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new dd87cdd45 [#5600] feat(API): Add Java API definition for ML model in
Gravitino (#5612)
dd87cdd45 is described below
commit dd87cdd45648a55f6366cdfb7dfa0c0edf6fb22b
Author: Jerry Shao <[email protected]>
AuthorDate: Mon Nov 25 11:28:21 2024 +0800
[#5600] feat(API): Add Java API definition for ML model in Gravitino (#5612)
### What changes were proposed in this pull request?
This PR adds the API definition for ML model and model catalog.
### Why are the changes needed?
This is the first step to support ML model management in Gravitino.
Fix: #5600
### Does this PR introduce _any_ user-facing change?
Yes.
### How was this patch tested?
Manual verification.
---
.../main/java/org/apache/gravitino/Catalog.java | 14 ++
.../java/org/apache/gravitino/MetadataObject.java | 4 +-
.../java/org/apache/gravitino/MetadataObjects.java | 5 +-
.../exceptions/ModelAlreadyExistsException.java | 50 +++++
.../ModelVersionAliasesAlreadyExistException.java | 50 +++++
.../gravitino/exceptions/NoSuchModelException.java | 49 +++++
.../exceptions/NoSuchModelVersionException.java | 49 +++++
.../java/org/apache/gravitino/model/Model.java | 92 ++++++++
.../org/apache/gravitino/model/ModelCatalog.java | 231 +++++++++++++++++++++
.../org/apache/gravitino/model/ModelVersion.java | 79 +++++++
10 files changed, 620 insertions(+), 3 deletions(-)
diff --git a/api/src/main/java/org/apache/gravitino/Catalog.java
b/api/src/main/java/org/apache/gravitino/Catalog.java
index 343ae5434..ba8cf28d2 100644
--- a/api/src/main/java/org/apache/gravitino/Catalog.java
+++ b/api/src/main/java/org/apache/gravitino/Catalog.java
@@ -24,6 +24,7 @@ import org.apache.gravitino.annotation.Evolving;
import org.apache.gravitino.authorization.SupportsRoles;
import org.apache.gravitino.file.FilesetCatalog;
import org.apache.gravitino.messaging.TopicCatalog;
+import org.apache.gravitino.model.ModelCatalog;
import org.apache.gravitino.rel.TableCatalog;
import org.apache.gravitino.tag.SupportsTags;
@@ -46,6 +47,9 @@ public interface Catalog extends Auditable {
/** Catalog Type for Message Queue, like Kafka://topic */
MESSAGING,
+ /** Catalog Type for ML model */
+ MODEL,
+
/** Catalog Type for test only. */
UNSUPPORTED;
@@ -63,6 +67,8 @@ public interface Catalog extends Auditable {
return FILESET;
case "messaging":
return MESSAGING;
+ case "model":
+ return MODEL;
default:
throw new IllegalArgumentException("Unknown catalog type: " + type);
}
@@ -178,6 +184,14 @@ public interface Catalog extends Auditable {
throw new UnsupportedOperationException("Catalog does not support topic
operations");
}
+ /**
+ * @return the {@link ModelCatalog} if the catalog supports model operations.
+ * @throws UnsupportedOperationException if the catalog does not support
model operations.
+ */
+ default ModelCatalog asModelCatalog() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException("Catalog does not support model
operations");
+ }
+
/**
* @return the {@link SupportsTags} if the catalog supports tag operations.
* @throws UnsupportedOperationException if the catalog does not support tag
operations.
diff --git a/api/src/main/java/org/apache/gravitino/MetadataObject.java
b/api/src/main/java/org/apache/gravitino/MetadataObject.java
index 7e94db194..05beafe9d 100644
--- a/api/src/main/java/org/apache/gravitino/MetadataObject.java
+++ b/api/src/main/java/org/apache/gravitino/MetadataObject.java
@@ -59,7 +59,9 @@ public interface MetadataObject {
/** A column is a sub-collection of the table that represents a group of
same type data. */
COLUMN,
/** A role is an object contains specific securable objects with
privileges */
- ROLE
+ ROLE,
+ /** A model is mapped to the model artifact in ML. */
+ MODEL
}
/**
diff --git a/api/src/main/java/org/apache/gravitino/MetadataObjects.java
b/api/src/main/java/org/apache/gravitino/MetadataObjects.java
index 49fe60187..74da23c10 100644
--- a/api/src/main/java/org/apache/gravitino/MetadataObjects.java
+++ b/api/src/main/java/org/apache/gravitino/MetadataObjects.java
@@ -83,8 +83,9 @@ public class MetadataObjects {
names.size() != 3
|| type == MetadataObject.Type.FILESET
|| type == MetadataObject.Type.TABLE
- || type == MetadataObject.Type.TOPIC,
- "If the length of names is 3, it must be FILESET, TABLE or TOPIC");
+ || type == MetadataObject.Type.TOPIC
+ || type == MetadataObject.Type.MODEL,
+ "If the length of names is 3, it must be FILESET, TABLE, TOPIC or
MODEL");
Preconditions.checkArgument(
names.size() != 4 || type == MetadataObject.Type.COLUMN,
diff --git
a/api/src/main/java/org/apache/gravitino/exceptions/ModelAlreadyExistsException.java
b/api/src/main/java/org/apache/gravitino/exceptions/ModelAlreadyExistsException.java
new file mode 100644
index 000000000..6ebb610af
--- /dev/null
+++
b/api/src/main/java/org/apache/gravitino/exceptions/ModelAlreadyExistsException.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** Exception thrown when a model with specified name already exists. */
+public class ModelAlreadyExistsException extends AlreadyExistsException {
+
+ /**
+ * Constructs a new exception with the specified detail message.
+ *
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public ModelAlreadyExistsException(@FormatString String message, Object...
args) {
+ super(message, args);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and cause.
+ *
+ * @param cause the cause.
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public ModelAlreadyExistsException(
+ Throwable cause, @FormatString String message, Object... args) {
+ super(cause, message, args);
+ }
+}
diff --git
a/api/src/main/java/org/apache/gravitino/exceptions/ModelVersionAliasesAlreadyExistException.java
b/api/src/main/java/org/apache/gravitino/exceptions/ModelVersionAliasesAlreadyExistException.java
new file mode 100644
index 000000000..b4754bebe
--- /dev/null
+++
b/api/src/main/java/org/apache/gravitino/exceptions/ModelVersionAliasesAlreadyExistException.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** Exception thrown when the model version aliases already exist. */
+public class ModelVersionAliasesAlreadyExistException extends
AlreadyExistsException {
+
+ /**
+ * Constructs a new exception with the specified detail message.
+ *
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public ModelVersionAliasesAlreadyExistException(@FormatString String
message, Object... args) {
+ super(message, args);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and cause.
+ *
+ * @param cause the cause.
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public ModelVersionAliasesAlreadyExistException(
+ Throwable cause, @FormatString String message, Object... args) {
+ super(cause, message, args);
+ }
+}
diff --git
a/api/src/main/java/org/apache/gravitino/exceptions/NoSuchModelException.java
b/api/src/main/java/org/apache/gravitino/exceptions/NoSuchModelException.java
new file mode 100644
index 000000000..056c83382
--- /dev/null
+++
b/api/src/main/java/org/apache/gravitino/exceptions/NoSuchModelException.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** Exception thrown when a model with specified name is not existed. */
+public class NoSuchModelException extends NotFoundException {
+
+ /**
+ * Constructs a new exception with the specified detail message.
+ *
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public NoSuchModelException(@FormatString String message, Object... args) {
+ super(message, args);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and cause.
+ *
+ * @param cause the cause.
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public NoSuchModelException(Throwable cause, String message, Object... args)
{
+ super(cause, message, args);
+ }
+}
diff --git
a/api/src/main/java/org/apache/gravitino/exceptions/NoSuchModelVersionException.java
b/api/src/main/java/org/apache/gravitino/exceptions/NoSuchModelVersionException.java
new file mode 100644
index 000000000..e85fce0c0
--- /dev/null
+++
b/api/src/main/java/org/apache/gravitino/exceptions/NoSuchModelVersionException.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.exceptions;
+
+import com.google.errorprone.annotations.FormatMethod;
+import com.google.errorprone.annotations.FormatString;
+
+/** Exception thrown when a model with specified version is not existed. */
+public class NoSuchModelVersionException extends NotFoundException {
+
+ /**
+ * Constructs a new exception with the specified detail message.
+ *
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public NoSuchModelVersionException(@FormatString String message, Object...
args) {
+ super(message, args);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and cause.
+ *
+ * @param cause the cause.
+ * @param message the detail message.
+ * @param args the arguments to the message.
+ */
+ @FormatMethod
+ public NoSuchModelVersionException(Throwable cause, String message,
Object... args) {
+ super(cause, message, args);
+ }
+}
diff --git a/api/src/main/java/org/apache/gravitino/model/Model.java
b/api/src/main/java/org/apache/gravitino/model/Model.java
new file mode 100644
index 000000000..fab4e0d53
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/model/Model.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.model;
+
+import java.util.Collections;
+import java.util.Map;
+import org.apache.gravitino.Auditable;
+import org.apache.gravitino.Namespace;
+import org.apache.gravitino.annotation.Evolving;
+import org.apache.gravitino.authorization.SupportsRoles;
+import org.apache.gravitino.tag.SupportsTags;
+
+/**
+ * An interface representing an ML model under a schema {@link Namespace}. A
model is a metadata
+ * object that represents the model artifact in ML. Users can register a model
object in Gravitino
+ * to manage the model metadata. The typical use case is to manage the model
in ML lifecycle with a
+ * unified way in Gravitino, and access the model artifact with a unified
identifier. Also, with the
+ * model registered in Gravitino, users can govern the model with Gravitino's
unified audit, tag,
+ * and role management.
+ *
+ * <p>The difference of Model and tabular data is that the model is
schema-free, and the main
+ * property of the model is the model artifact URL. The difference compared to
the fileset is that
+ * the model is versioned, and the model object contains the version
information.
+ */
+@Evolving
+public interface Model extends Auditable {
+
+ /** @return Name of the model object. */
+ String name();
+
+ /**
+ * The comment of the model object. This is the general description of the
model object. User can
+ * still add more detailed information in the model version.
+ *
+ * @return The comment of the model object. Null is returned if no comment
is set.
+ */
+ default String comment() {
+ return null;
+ }
+
+ /**
+ * The properties of the model object. The properties are key-value pairs
that can be used to
+ * store additional information of the model object. The properties are
optional.
+ *
+ * <p>Users can still specify the properties in the model version for
different information.
+ *
+ * @return the properties of the model object.
+ */
+ default Map<String, String> properties() {
+ return Collections.emptyMap();
+ }
+
+ /**
+ * The latest version of the model object. The latest version is the version
number of the latest
+ * model checkpoint / snapshot that is linked to the registered model.
+ *
+ * @return The latest version of the model object.
+ */
+ int latestVersion();
+
+ /**
+ * @return The {@link SupportsTags} if the model supports tag operations.
+ * @throws UnsupportedOperationException If the model does not support tag
operations.
+ */
+ default SupportsTags supportsTags() {
+ throw new UnsupportedOperationException("Model does not support tag
operations.");
+ }
+
+ /**
+ * @return The {@link SupportsRoles} if the model supports role operations.
+ * @throws UnsupportedOperationException If the model does not support role
operations.
+ */
+ default SupportsRoles supportsRoles() {
+ throw new UnsupportedOperationException("Model does not support role
operations.");
+ }
+}
diff --git a/api/src/main/java/org/apache/gravitino/model/ModelCatalog.java
b/api/src/main/java/org/apache/gravitino/model/ModelCatalog.java
new file mode 100644
index 000000000..d7429fd02
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/model/ModelCatalog.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.model;
+
+import java.util.Map;
+import org.apache.gravitino.NameIdentifier;
+import org.apache.gravitino.Namespace;
+import org.apache.gravitino.annotation.Evolving;
+import org.apache.gravitino.exceptions.ModelAlreadyExistsException;
+import
org.apache.gravitino.exceptions.ModelVersionAliasesAlreadyExistException;
+import org.apache.gravitino.exceptions.NoSuchModelException;
+import org.apache.gravitino.exceptions.NoSuchModelVersionException;
+import org.apache.gravitino.exceptions.NoSuchSchemaException;
+
+/**
+ * The ModelCatalog interface defines the public API for managing model
objects in a schema. If the
+ * catalog implementation supports model objects, it should implement this
interface.
+ */
+@Evolving
+public interface ModelCatalog {
+
+ /**
+ * List the models in a schema namespace from the catalog.
+ *
+ * @param namespace A schema namespace.
+ * @return An array of model identifiers in the namespace.
+ * @throws NoSuchSchemaException If the schema does not exist.
+ */
+ NameIdentifier[] listModels(Namespace namespace) throws
NoSuchSchemaException;
+
+ /**
+ * Get a model metadata by {@link NameIdentifier} from the catalog.
+ *
+ * @param ident A model identifier.
+ * @return The model metadata.
+ * @throws NoSuchModelException If the model does not exist.
+ */
+ Model getModel(NameIdentifier ident) throws NoSuchModelException;
+
+ /**
+ * Check if a model exists using an {@link NameIdentifier} from the catalog.
+ *
+ * @param ident A model identifier.
+ * @return true If the model exists, false if the model does not exist.
+ */
+ default boolean modelExists(NameIdentifier ident) {
+ try {
+ getModel(ident);
+ return true;
+ } catch (NoSuchModelException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Register a model in the catalog if the model is not existed, otherwise
the {@link
+ * ModelAlreadyExistsException} will be thrown. The {@link Model} object
will be created when the
+ * model is registered, users can call {@link
ModelCatalog#linkModelVersion(NameIdentifier,
+ * String, String[], String, Map)} to link the model version to the
registered {@link Model}.
+ *
+ * @param ident The name identifier of the model.
+ * @param comment The comment of the model. The comment is optional and can
be null.
+ * @param properties The properties of the model. The properties are
optional and can be null or
+ * empty.
+ * @return The registered model object.
+ * @throws ModelAlreadyExistsException If the model already registered.
+ */
+ default Model registerModel(NameIdentifier ident, String comment,
Map<String, String> properties)
+ throws ModelAlreadyExistsException {
+ return registerModel(ident, null, new String[0], comment, properties);
+ }
+
+ /**
+ * Register a model in the catalog if the model is not existed, otherwise
the {@link
+ * ModelAlreadyExistsException} will be thrown. The {@link Model} object
will be created when the
+ * model is registered, in the meantime, the model version (version 0) will
also be created and
+ * linked to the registered model.
+ *
+ * @param ident The name identifier of the model.
+ * @param uri The model artifact URI.
+ * @param aliases The aliases of the model version. The alias are optional
and can be empty.
+ * @param comment The comment of the model. The comment is optional and can
be null.
+ * @param properties The properties of the model. The properties are
optional and can be null or
+ * empty.
+ * @return The registered model object.
+ * @throws ModelAlreadyExistsException If the model already registered.
+ * @throws ModelVersionAliasesAlreadyExistException If the aliases already
exist in the model.
+ */
+ Model registerModel(
+ NameIdentifier ident,
+ String uri,
+ String[] aliases,
+ String comment,
+ Map<String, String> properties)
+ throws ModelAlreadyExistsException,
ModelVersionAliasesAlreadyExistException;
+
+ /**
+ * Delete the model from the catalog. If the model does not exist, return
false. Otherwise, return
+ * true. The deletion of the model will also delete all the model versions
linked to this model.
+ *
+ * @param ident The name identifier of the model.
+ * @return True if the model is deleted, false if the model does not exist.
+ */
+ boolean deleteModel(NameIdentifier ident);
+
+ /**
+ * List all the versions of the register model by {@link NameIdentifier} in
the catalog.
+ *
+ * @param ident The name identifier of the model.
+ * @return An array of version numbers of the model.
+ * @throws NoSuchModelException If the model does not exist.
+ */
+ int[] listModelVersions(NameIdentifier ident) throws NoSuchModelException;
+
+ /**
+ * Get a model version by the {@link NameIdentifier} and version number from
the catalog.
+ *
+ * @param ident The name identifier of the model.
+ * @param version The version number of the model.
+ * @return The model version object.
+ * @throws NoSuchModelVersionException If the model version does not exist.
+ */
+ ModelVersion getModelVersion(NameIdentifier ident, int version)
+ throws NoSuchModelVersionException;
+
+ /**
+ * Get a model version by the {@link NameIdentifier} and version alias from
the catalog.
+ *
+ * @param ident The name identifier of the model.
+ * @param alias The version alias of the model.
+ * @return The model version object.
+ * @throws NoSuchModelVersionException If the model version does not exist.
+ */
+ ModelVersion getModelVersion(NameIdentifier ident, String alias)
+ throws NoSuchModelVersionException;
+
+ /**
+ * Check if the model version exists by the {@link NameIdentifier} and
version number. If the
+ * model version exists, return true, otherwise return false.
+ *
+ * @param ident The name identifier of the model.
+ * @param version The version number of the model.
+ * @return True if the model version exists, false if the model version does
not exist.
+ */
+ default boolean modelVersionExists(NameIdentifier ident, int version) {
+ try {
+ getModelVersion(ident, version);
+ return true;
+ } catch (NoSuchModelVersionException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Check if the model version exists by the {@link NameIdentifier} and
version alias. If the model
+ * version exists, return true, otherwise return false.
+ *
+ * @param ident The name identifier of the model.
+ * @param alias The version alias of the model.
+ * @return True if the model version exists, false if the model version does
not exist.
+ */
+ default boolean modelVersionExists(NameIdentifier ident, String alias) {
+ try {
+ getModelVersion(ident, alias);
+ return true;
+ } catch (NoSuchModelVersionException e) {
+ return false;
+ }
+ }
+
+ /**
+ * Link a new model version to the registered model object. The new model
version will be added to
+ * the model object. If the model object does not exist, it will throw an
exception. If the
+ * version alias already exists in the model, it will throw an exception.
+ *
+ * @param ident The name identifier of the model.
+ * @param uri The URI of the model version artifact.
+ * @param aliases The aliases of the model version. The aliases should be
unique in this model,
+ * otherwise the {@link ModelVersionAliasesAlreadyExistException} will
be thrown. The aliases
+ * are optional and can be empty.
+ * @param comment The comment of the model version. The comment is optional
and can be null.
+ * @param properties The properties of the model version. The properties are
optional and can be
+ * null or empty.
+ * @return The model version object.
+ * @throws NoSuchModelException If the model does not exist.
+ * @throws ModelVersionAliasesAlreadyExistException If the aliases already
exist in the model.
+ */
+ ModelVersion linkModelVersion(
+ NameIdentifier ident,
+ String uri,
+ String[] aliases,
+ String comment,
+ Map<String, String> properties)
+ throws NoSuchModelException, ModelVersionAliasesAlreadyExistException;
+
+ /**
+ * Delete the model version by the {@link NameIdentifier} and version
number. If the model version
+ * does not exist, return false. If the model version is deleted, return
true.
+ *
+ * @param ident The name identifier of the model.
+ * @param version The version number of the model.
+ * @return True if the model version is deleted, false if the model version
does not exist.
+ */
+ boolean deleteModelVersion(NameIdentifier ident, int version);
+
+ /**
+ * Delete the model version by the {@link NameIdentifier} and version alias.
If the model version
+ * does not exist, return false. If the model version is deleted, return
true.
+ *
+ * @param ident The name identifier of the model.
+ * @param alias The version alias of the model.
+ * @return True if the model version is deleted, false if the model version
does not exist.
+ */
+ boolean deleteModelVersion(NameIdentifier ident, String alias);
+}
diff --git a/api/src/main/java/org/apache/gravitino/model/ModelVersion.java
b/api/src/main/java/org/apache/gravitino/model/ModelVersion.java
new file mode 100644
index 000000000..2557c8607
--- /dev/null
+++ b/api/src/main/java/org/apache/gravitino/model/ModelVersion.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.gravitino.model;
+
+import java.util.Collections;
+import java.util.Map;
+import org.apache.gravitino.Auditable;
+import org.apache.gravitino.annotation.Evolving;
+
+/**
+ * An interface representing a single model checkpoint under a model {@link
Model}. A model version
+ * is a snapshot at a point of time of a model artifact in ML. Users can link
a model version to a
+ * registered model.
+ */
+@Evolving
+public interface ModelVersion extends Auditable {
+
+ /**
+ * The version of this model object. The version number is an integer number
starts from 0. Each
+ * time the model checkpoint / snapshot is linked to the registered, the
version number will be
+ * increased by 1.
+ *
+ * @return The version of the model object.
+ */
+ int version();
+
+ /**
+ * The comment of this model version. This comment can be different from the
comment of the model
+ * to provide more detailed information about this version.
+ *
+ * @return The comment of the model version. Null is returned if no comment
is set.
+ */
+ default String comment() {
+ return null;
+ }
+
+ /**
+ * The aliases of this model version. The aliases are the alternative names
of the model version.
+ * The aliases are optional. The aliases are unique for a model version. If
the alias is already
+ * set to one model version, it cannot be set to another model version.
+ *
+ * @return The aliases of the model version.
+ */
+ String[] aliases();
+
+ /**
+ * The URI of the model artifact. The URI is the location of the model
artifact. The URI can be a
+ * file path or a remote URI.
+ *
+ * @return The URI of the model artifact.
+ */
+ String uri();
+
+ /**
+ * The properties of the model version. The properties are key-value pairs
that can be used to
+ * store additional information of the model version. The properties are
optional.
+ *
+ * @return the properties of the model version.
+ */
+ default Map<String, String> properties() {
+ return Collections.emptyMap();
+ }
+}