This is an automated email from the ASF dual-hosted git repository.

yuqi4733 pushed a commit to branch branch-0.9
in repository https://gitbox.apache.org/repos/asf/gravitino.git


The following commit(s) were added to refs/heads/branch-0.9 by this push:
     new 75a8f0e6f5 [#7686] improvement(client-java): Correct URL encode path 
in alterModelVersion in GenericModelCatalog.java (#7694)
75a8f0e6f5 is described below

commit 75a8f0e6f5bd75ee3d3bb0c8adb93ca94ebada20
Author: Sua Bae <[email protected]>
AuthorDate: Tue Jul 15 10:30:10 2025 +0900

    [#7686] improvement(client-java): Correct URL encode path in 
alterModelVersion in GenericModelCatalog.java (#7694)
    
    ### What changes were proposed in this pull request?
    
    The cherry-pick conflicts were successfully resolved by manually
    
    ### Why are the changes needed?
    
    
    Close: #7686
    
    ### Does this PR introduce _any_ user-facing change?
    
    None
    
    ### How was this patch tested?
    
    using the client-java module's tests.
---
 .../gravitino/client/GenericModelCatalog.java      |   4 +-
 .../gravitino/client/TestGenericModelCatalog.java  | 207 +++++++++++++--------
 2 files changed, 137 insertions(+), 74 deletions(-)

diff --git 
a/clients/client-java/src/main/java/org/apache/gravitino/client/GenericModelCatalog.java
 
b/clients/client-java/src/main/java/org/apache/gravitino/client/GenericModelCatalog.java
index c10b5bbc40..eeec6be5d8 100644
--- 
a/clients/client-java/src/main/java/org/apache/gravitino/client/GenericModelCatalog.java
+++ 
b/clients/client-java/src/main/java/org/apache/gravitino/client/GenericModelCatalog.java
@@ -329,7 +329,9 @@ class GenericModelCatalog extends BaseSchemaCatalog 
implements ModelCatalog {
     NameIdentifier modelFullIdent = modelFullNameIdentifier(ident);
     ModelVersionResponse resp =
         restClient.put(
-            formatModelVersionRequestPath(modelFullIdent) + "/aliases/" + 
alias,
+            formatModelVersionRequestPath(modelFullIdent)
+                + "/aliases/"
+                + RESTUtils.encodeString(alias),
             req,
             ModelVersionResponse.class,
             Collections.emptyMap(),
diff --git 
a/clients/client-java/src/test/java/org/apache/gravitino/client/TestGenericModelCatalog.java
 
b/clients/client-java/src/test/java/org/apache/gravitino/client/TestGenericModelCatalog.java
index 1fdea36228..2c190288cc 100644
--- 
a/clients/client-java/src/test/java/org/apache/gravitino/client/TestGenericModelCatalog.java
+++ 
b/clients/client-java/src/test/java/org/apache/gravitino/client/TestGenericModelCatalog.java
@@ -53,11 +53,13 @@ import 
org.apache.gravitino.exceptions.NoSuchModelVersionException;
 import org.apache.gravitino.exceptions.NoSuchSchemaException;
 import org.apache.gravitino.model.Model;
 import org.apache.gravitino.model.ModelVersion;
+import org.apache.gravitino.rest.RESTUtils;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.Method;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 public class TestGenericModelCatalog extends TestBase {
 
@@ -101,20 +103,24 @@ public class TestGenericModelCatalog extends TestBase {
         metalake.createCatalog(CATALOG_NAME, Catalog.Type.MODEL, "comment", 
Collections.emptyMap());
   }
 
-  @Test
-  public void testListModels() throws JsonProcessingException {
-    NameIdentifier modelId1 = NameIdentifier.of("schema1", "model1");
-    NameIdentifier modelId2 = NameIdentifier.of("schema1", "model2");
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1/model2", "스키마1/모델1/모델2"})
+  public void testListModels(String input) throws JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String[] modelNames = new String[] {split[1], split[2]};
+    NameIdentifier modelId1 = NameIdentifier.of(schemaName, modelNames[0]);
+    NameIdentifier modelId2 = NameIdentifier.of(schemaName, modelNames[1]);
 
     NameIdentifier resultModelId1 =
-        NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", "model1");
+        NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelNames[0]);
     NameIdentifier resultModelId2 =
-        NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", "model2");
+        NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelNames[1]);
 
     String modelPath =
         withSlash(
             GenericModelCatalog.formatModelRequestPath(
-                Namespace.of(METALAKE_NAME, CATALOG_NAME, "schema1")));
+                Namespace.of(METALAKE_NAME, CATALOG_NAME, schemaName)));
 
     EntityListResponse resp =
         new EntityListResponse(new NameIdentifier[] {resultModelId1, 
resultModelId2});
@@ -143,15 +149,20 @@ public class TestGenericModelCatalog extends TestBase {
         "internal error");
   }
 
-  @Test
-  public void testGetModel() throws JsonProcessingException {
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1", "스키마1/모델1"})
+  public void testGetModel(String input) throws JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelPath =
         withSlash(
             GenericModelCatalog.formatModelRequestPath(
-                    Namespace.of(METALAKE_NAME, CATALOG_NAME, "schema1"))
+                    Namespace.of(METALAKE_NAME, CATALOG_NAME, schemaName))
                 + "/"
-                + modelId.name());
+                + RESTUtils.encodeString(modelId.name()));
 
     ModelDTO modelDTO = mockModelDTO("model1", 0, "model comment", 
Collections.emptyMap());
     ModelResponse resp = new ModelResponse(modelDTO);
@@ -178,10 +189,14 @@ public class TestGenericModelCatalog extends TestBase {
         RuntimeException.class, () -> 
catalog.asModelCatalog().getModel(modelId), "internal error");
   }
 
-  @Test
-  public void testRegisterModel() throws JsonProcessingException {
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
-    ModelDTO modelDTO = mockModelDTO("model1", 0, "model comment", 
Collections.emptyMap());
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1", "스키마1/모델1"})
+  public void testRegisterModel(String input) throws JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
+    ModelDTO modelDTO = mockModelDTO(schemaName, 0, "model comment", 
Collections.emptyMap());
     ModelResponse resp = new ModelResponse(modelDTO);
     ModelRegisterRequest request =
         new ModelRegisterRequest(modelId.name(), "model comment", 
Collections.emptyMap());
@@ -189,7 +204,8 @@ public class TestGenericModelCatalog extends TestBase {
     String modelPath =
         withSlash(
             GenericModelCatalog.formatModelRequestPath(
-                Namespace.of(METALAKE_NAME, CATALOG_NAME, "schema1")));
+                Namespace.of(METALAKE_NAME, CATALOG_NAME, schemaName)));
+
     buildMockResource(Method.POST, modelPath, request, resp, HttpStatus.SC_OK);
 
     Model model =
@@ -237,15 +253,20 @@ public class TestGenericModelCatalog extends TestBase {
         "internal error");
   }
 
-  @Test
-  public void testDeleteModel() throws JsonProcessingException {
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1", "스키마1/모델1"})
+  public void testDeleteModel(String input) throws JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelPath =
         withSlash(
             GenericModelCatalog.formatModelRequestPath(
-                    Namespace.of(METALAKE_NAME, CATALOG_NAME, "schema1"))
+                    Namespace.of(METALAKE_NAME, CATALOG_NAME, schemaName))
                 + "/"
-                + modelId.name());
+                + RESTUtils.encodeString(modelId.name()));
 
     DropResponse resp = new DropResponse(true);
     buildMockResource(Method.DELETE, modelPath, null, resp, HttpStatus.SC_OK);
@@ -262,13 +283,17 @@ public class TestGenericModelCatalog extends TestBase {
         "internal error");
   }
 
-  @Test
-  public void testListModelVersions() throws JsonProcessingException {
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1", "스키마1/모델1"})
+  public void testListModelVersions(String input) throws 
JsonProcessingException {
+    String split[] = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelVersionPath =
         withSlash(
             GenericModelCatalog.formatModelVersionRequestPath(
-                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", 
"model1"))
+                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelName))
                 + "/versions");
 
     int[] expectedVersions = new int[] {0, 1, 2};
@@ -299,13 +324,17 @@ public class TestGenericModelCatalog extends TestBase {
         "internal error");
   }
 
-  @Test
-  public void testGetModelVersion() throws JsonProcessingException {
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1", "스키마1/모델1"})
+  public void testGetModelVersion(String input) throws JsonProcessingException 
{
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelVersionPath =
         withSlash(
             GenericModelCatalog.formatModelVersionRequestPath(
-                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", 
"model1"))
+                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelName))
                 + "/versions/0");
 
     ModelVersionDTO mockModelVersion =
@@ -339,22 +368,27 @@ public class TestGenericModelCatalog extends TestBase {
         "internal error");
   }
 
-  @Test
-  public void testGetModelVersionByAlias() throws JsonProcessingException {
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1/alias1/alias2", "스키마1/모델1/별칭1/별칭2"})
+  public void testGetModelVersionByAlias(String input) throws 
JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+    String[] aliasNames = new String[] {split[2], split[3]};
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelVersionPath =
         withSlash(
             GenericModelCatalog.formatModelVersionRequestPath(
-                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", 
"model1"))
-                + "/aliases/alias1");
+                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelName))
+                + "/aliases/"
+                + RESTUtils.encodeString(aliasNames[0]));
 
     ModelVersionDTO mockModelVersion =
-        mockModelVersion(
-            0, "uri", new String[] {"alias1", "alias2"}, "comment", 
Collections.emptyMap());
+        mockModelVersion(0, "uri", aliasNames, "comment", 
Collections.emptyMap());
     ModelVersionResponse resp = new ModelVersionResponse(mockModelVersion);
     buildMockResource(Method.GET, modelVersionPath, null, resp, 
HttpStatus.SC_OK);
 
-    ModelVersion modelVersion = 
catalog.asModelCatalog().getModelVersion(modelId, "alias1");
+    ModelVersion modelVersion = 
catalog.asModelCatalog().getModelVersion(modelId, aliasNames[0]);
     compareModelVersion(mockModelVersion, modelVersion);
 
     // Throw model version not found exception
@@ -365,7 +399,7 @@ public class TestGenericModelCatalog extends TestBase {
 
     Assertions.assertThrows(
         NoSuchModelVersionException.class,
-        () -> catalog.asModelCatalog().getModelVersion(modelId, "alias1"),
+        () -> catalog.asModelCatalog().getModelVersion(modelId, aliasNames[0]),
         "model version not found");
 
     // Throw RuntimeException
@@ -375,17 +409,21 @@ public class TestGenericModelCatalog extends TestBase {
 
     Assertions.assertThrows(
         RuntimeException.class,
-        () -> catalog.asModelCatalog().getModelVersion(modelId, "alias1"),
+        () -> catalog.asModelCatalog().getModelVersion(modelId, aliasNames[0]),
         "internal error");
   }
 
-  @Test
-  public void testLinkModelVersion() throws JsonProcessingException {
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1", "스키마1/모델1"})
+  public void testLinkModelVersion(String input) throws 
JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelVersionPath =
         withSlash(
             GenericModelCatalog.formatModelVersionRequestPath(
-                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", 
"model1"))
+                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelName))
                 + "/versions");
 
     ModelVersionLinkRequest request =
@@ -462,13 +500,17 @@ public class TestGenericModelCatalog extends TestBase {
         "internal error");
   }
 
-  @Test
-  public void testDeleteModelVersion() throws JsonProcessingException {
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1", "스키마1/모델1"})
+  public void testDeleteModelVersion(String input) throws 
JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelVersionPath =
         withSlash(
             GenericModelCatalog.formatModelVersionRequestPath(
-                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", 
"model1"))
+                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelName))
                 + "/versions/0");
 
     DropResponse resp = new DropResponse(true);
@@ -487,19 +529,25 @@ public class TestGenericModelCatalog extends TestBase {
         "internal error");
   }
 
-  @Test
-  public void testDeleteModelVersionByAlias() throws JsonProcessingException {
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1/alias1", "스키마1/모델1/별칭1"})
+  public void testDeleteModelVersionByAlias(String input) throws 
JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+    String aliasName = split[2];
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelVersionPath =
         withSlash(
             GenericModelCatalog.formatModelVersionRequestPath(
-                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", 
"model1"))
-                + "/aliases/alias1");
+                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelName))
+                + "/aliases/"
+                + RESTUtils.encodeString(aliasName));
 
     DropResponse resp = new DropResponse(true);
     buildMockResource(Method.DELETE, modelVersionPath, null, resp, 
HttpStatus.SC_OK);
 
-    Assertions.assertTrue(catalog.asModelCatalog().deleteModelVersion(modelId, 
"alias1"));
+    Assertions.assertTrue(catalog.asModelCatalog().deleteModelVersion(modelId, 
aliasName));
 
     // Test RuntimeException
     ErrorResponse errResp = ErrorResponse.internalError("internal error");
@@ -508,23 +556,26 @@ public class TestGenericModelCatalog extends TestBase {
 
     Assertions.assertThrows(
         RuntimeException.class,
-        () -> catalog.asModelCatalog().deleteModelVersion(modelId, "alias1"),
+        () -> catalog.asModelCatalog().deleteModelVersion(modelId, aliasName),
         "internal error");
   }
 
-  @Test
-  public void testAlterModel() throws JsonProcessingException {
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1/new_model1", "스키마1/모델1/새로운_모델1"})
+  public void testAlterModel(String input) throws JsonProcessingException {
+    String[] split = input.split("/");
+    String schema = split[0];
+    String oldName = split[1];
+    String newName = split[2];
     String comment = "comment";
-    String schema = "schema1";
-    String oldName = "model1";
-    String newName = "new_model";
+
     NameIdentifier modelId = NameIdentifier.of(schema, oldName);
     String modelPath =
         withSlash(
             GenericModelCatalog.formatModelRequestPath(
                     Namespace.of(METALAKE_NAME, CATALOG_NAME, schema))
                 + "/"
-                + modelId.name());
+                + RESTUtils.encodeString(modelId.name()));
 
     // Test rename the model
     ModelUpdateRequest.RenameModelRequest renameModelReq =
@@ -572,18 +623,22 @@ public class TestGenericModelCatalog extends TestBase {
         "internal error");
   }
 
-  @Test
-  void testUpdateModelVersionComment() throws JsonProcessingException {
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1/alias1/alias2", "스키마1/모델1/별칭1/별칭2"})
+  void testUpdateModelVersionComment(String input) throws 
JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+    String[] aliases = new String[] {split[2], split[3]};
     String newComment = "new comment";
     String uri = "uri";
     int version = 0;
-    String[] aliases = new String[] {"alias1", "alias2"};
 
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelVersionPath =
         withSlash(
             GenericModelCatalog.formatModelVersionRequestPath(
-                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", 
"model1"))
+                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelName))
                 + "/versions/0");
 
     ModelVersionDTO mockModelVersion =
@@ -646,19 +701,25 @@ public class TestGenericModelCatalog extends TestBase {
         "internal error");
   }
 
-  @Test
-  void testUpdateModelVersionCommentByAlias() throws JsonProcessingException {
+  @ParameterizedTest
+  @ValueSource(strings = {"schema1/model1/alias1/alias2", "스키마1/모델1/별칭1/별칭2"})
+  void testUpdateModelVersionCommentByAlias(String input) throws 
JsonProcessingException {
+    String[] split = input.split("/");
+    String schemaName = split[0];
+    String modelName = split[1];
+    String[] aliases = new String[] {split[2], split[3]};
+
     String newComment = "new comment";
     String uri = "uri";
     int version = 0;
-    String[] aliases = new String[] {"alias1", "alias2"};
 
-    NameIdentifier modelId = NameIdentifier.of("schema1", "model1");
+    NameIdentifier modelId = NameIdentifier.of(schemaName, modelName);
     String modelVersionPath =
         withSlash(
             GenericModelCatalog.formatModelVersionRequestPath(
-                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, "schema1", 
"model1"))
-                + "/aliases/alias1");
+                    NameIdentifier.of(METALAKE_NAME, CATALOG_NAME, schemaName, 
modelName))
+                + "/aliases/"
+                + RESTUtils.encodeString(aliases[0]));
 
     ModelVersionDTO mockModelVersion =
         mockModelVersion(version, uri, aliases, newComment, 
Collections.emptyMap());

Reply via email to