stevenzwu commented on code in PR #14142:
URL: https://github.com/apache/iceberg/pull/14142#discussion_r2919802280


##########
api/src/main/java/org/apache/iceberg/catalog/CatalogObjectIdentifier.java:
##########
@@ -0,0 +1,111 @@
+/*
+ * 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.iceberg.catalog;
+
+import java.util.Arrays;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import org.apache.iceberg.relocated.com.google.common.base.Joiner;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+
+/**
+ * Reference to a named object in a {@link Catalog}, such as {@link 
Namespace}, {@link
+ * org.apache.iceberg.Table}, or {@link org.apache.iceberg.view.View}.
+ */
+public class CatalogObjectIdentifier {

Review Comment:
   this new concept makes sense to me. It is also useful for the universal load 
endpoint (table, view, MV, index) that we talked about in the community 
discussion.



##########
api/src/main/java/org/apache/iceberg/catalog/CatalogObjectIdentifier.java:
##########
@@ -0,0 +1,111 @@
+/*
+ * 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.iceberg.catalog;
+
+import java.util.Arrays;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import org.apache.iceberg.relocated.com.google.common.base.Joiner;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+
+/**
+ * Reference to a named object in a {@link Catalog}, such as {@link 
Namespace}, {@link
+ * org.apache.iceberg.Table}, or {@link org.apache.iceberg.view.View}.
+ */
+public class CatalogObjectIdentifier {
+  private static final CatalogObjectIdentifier EMPTY_CATALOG_OBJECT =
+      new CatalogObjectIdentifier(new String[] {});
+  private static final Joiner DOT = Joiner.on(".");
+  private static final Predicate<String> CONTAINS_NULL_CHARACTER =
+      Pattern.compile("\u0000", Pattern.UNICODE_CHARACTER_CLASS).asPredicate();
+
+  public static CatalogObjectIdentifier empty() {
+    return EMPTY_CATALOG_OBJECT;
+  }
+
+  public static CatalogObjectIdentifier of(String... levels) {
+    Preconditions.checkArgument(
+        null != levels, "Cannot create CatalogObjectIdentifier from null 
array");
+    if (levels.length == 0) {

Review Comment:
   this should not be allowed. A valid catalog object identifier should have at 
least one level of non-empty string value.
   
   For comparison with existing code, namespace can be empty, but table 
identifier name must be non-empty.



##########
api/src/main/java/org/apache/iceberg/catalog/CatalogObjectIdentifier.java:
##########
@@ -0,0 +1,111 @@
+/*
+ * 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.iceberg.catalog;
+
+import java.util.Arrays;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import org.apache.iceberg.relocated.com.google.common.base.Joiner;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+
+/**
+ * Reference to a named object in a {@link Catalog}, such as {@link 
Namespace}, {@link
+ * org.apache.iceberg.Table}, or {@link org.apache.iceberg.view.View}.
+ */
+public class CatalogObjectIdentifier {
+  private static final CatalogObjectIdentifier EMPTY_CATALOG_OBJECT =
+      new CatalogObjectIdentifier(new String[] {});
+  private static final Joiner DOT = Joiner.on(".");
+  private static final Predicate<String> CONTAINS_NULL_CHARACTER =
+      Pattern.compile("\u0000", Pattern.UNICODE_CHARACTER_CLASS).asPredicate();
+
+  public static CatalogObjectIdentifier empty() {
+    return EMPTY_CATALOG_OBJECT;
+  }
+
+  public static CatalogObjectIdentifier of(String... levels) {
+    Preconditions.checkArgument(
+        null != levels, "Cannot create CatalogObjectIdentifier from null 
array");
+    if (levels.length == 0) {
+      return empty();
+    }
+
+    for (String level : levels) {
+      Preconditions.checkNotNull(
+          level, "Cannot create a CatalogObjectIdentifier with a null level");
+      Preconditions.checkArgument(
+          !CONTAINS_NULL_CHARACTER.test(level),
+          "Cannot create a CatalogObjectIdentifier with the null-byte 
character");
+    }
+
+    return new CatalogObjectIdentifier(levels);
+  }
+
+  public static CatalogObjectIdentifier of(String name) {
+    Preconditions.checkNotNull(name, "Cannot create CatalogObjectIdentifier 
from null name");

Review Comment:
   not null and not empty



##########
api/src/main/java/org/apache/iceberg/catalog/CatalogObjectUuid.java:
##########
@@ -0,0 +1,81 @@
+/*
+ * 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.iceberg.catalog;
+
+import java.util.Objects;
+import org.apache.iceberg.relocated.com.google.common.base.MoreObjects;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+
+/**
+ * Identifies a {@link org.apache.iceberg.Table} or {@link 
org.apache.iceberg.view.View} by UUID.
+ */
+public class CatalogObjectUuid {

Review Comment:
   I don't quite understand the need of this class. 



##########
api/src/main/java/org/apache/iceberg/catalog/CatalogObjectIdentifier.java:
##########
@@ -0,0 +1,111 @@
+/*
+ * 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.iceberg.catalog;
+
+import java.util.Arrays;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import org.apache.iceberg.relocated.com.google.common.base.Joiner;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+
+/**
+ * Reference to a named object in a {@link Catalog}, such as {@link 
Namespace}, {@link
+ * org.apache.iceberg.Table}, or {@link org.apache.iceberg.view.View}.
+ */
+public class CatalogObjectIdentifier {
+  private static final CatalogObjectIdentifier EMPTY_CATALOG_OBJECT =
+      new CatalogObjectIdentifier(new String[] {});
+  private static final Joiner DOT = Joiner.on(".");
+  private static final Predicate<String> CONTAINS_NULL_CHARACTER =
+      Pattern.compile("\u0000", Pattern.UNICODE_CHARACTER_CLASS).asPredicate();
+
+  public static CatalogObjectIdentifier empty() {
+    return EMPTY_CATALOG_OBJECT;
+  }
+
+  public static CatalogObjectIdentifier of(String... levels) {
+    Preconditions.checkArgument(
+        null != levels, "Cannot create CatalogObjectIdentifier from null 
array");
+    if (levels.length == 0) {
+      return empty();
+    }
+
+    for (String level : levels) {
+      Preconditions.checkNotNull(

Review Comment:
   I see the current `Namespace` class doesn't enforce non-empty level string. 
But I am still wondering if it is valid?



##########
api/src/main/java/org/apache/iceberg/catalog/CatalogObjectType.java:
##########
@@ -0,0 +1,52 @@
+/*
+ * 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.iceberg.catalog;
+
+import java.util.Arrays;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+
+/** Enum representing {@link CatalogObject} type. */
+public enum CatalogObjectType {
+  NAMESPACE("namespace"),

Review Comment:
   there is also a proposal from @talatuyarer on adding UUID to namespace 
objects in the dev ML. Here is the PR:  
   https://github.com/apache/iceberg/pull/15317



##########
api/src/main/java/org/apache/iceberg/catalog/CatalogObjectIdentifier.java:
##########
@@ -0,0 +1,111 @@
+/*
+ * 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.iceberg.catalog;
+
+import java.util.Arrays;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import org.apache.iceberg.relocated.com.google.common.base.Joiner;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+
+/**
+ * Reference to a named object in a {@link Catalog}, such as {@link 
Namespace}, {@link
+ * org.apache.iceberg.Table}, or {@link org.apache.iceberg.view.View}.
+ */
+public class CatalogObjectIdentifier {
+  private static final CatalogObjectIdentifier EMPTY_CATALOG_OBJECT =
+      new CatalogObjectIdentifier(new String[] {});
+  private static final Joiner DOT = Joiner.on(".");
+  private static final Predicate<String> CONTAINS_NULL_CHARACTER =
+      Pattern.compile("\u0000", Pattern.UNICODE_CHARACTER_CLASS).asPredicate();
+
+  public static CatalogObjectIdentifier empty() {
+    return EMPTY_CATALOG_OBJECT;
+  }
+
+  public static CatalogObjectIdentifier of(String... levels) {
+    Preconditions.checkArgument(
+        null != levels, "Cannot create CatalogObjectIdentifier from null 
array");
+    if (levels.length == 0) {
+      return empty();
+    }
+
+    for (String level : levels) {
+      Preconditions.checkNotNull(
+          level, "Cannot create a CatalogObjectIdentifier with a null level");
+      Preconditions.checkArgument(
+          !CONTAINS_NULL_CHARACTER.test(level),
+          "Cannot create a CatalogObjectIdentifier with the null-byte 
character");
+    }
+
+    return new CatalogObjectIdentifier(levels);
+  }
+
+  public static CatalogObjectIdentifier of(String name) {
+    Preconditions.checkNotNull(name, "Cannot create CatalogObjectIdentifier 
from null name");
+
+    return of(name.split("\\."));
+  }
+
+  private final String[] levels;
+
+  private CatalogObjectIdentifier(String[] levels) {
+    this.levels = levels;
+  }
+
+  public String[] levels() {

Review Comment:
   nit: add javadoc to public API methods



##########
core/src/main/java/org/apache/iceberg/rest/responses/QueryEventsResponse.java:
##########
@@ -0,0 +1,39 @@
+/*
+ * 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.iceberg.rest.responses;
+
+import java.util.List;
+import org.apache.iceberg.rest.RESTResponse;
+import org.apache.iceberg.rest.events.Event;
+import org.immutables.value.Value;
+
+/** Standard response body for event queries */
[email protected]
+public interface QueryEventsResponse extends RESTResponse {
+  String nextPageToken();

Review Comment:
   this was changed to `continuationToken` in the spec PR?



##########
core/src/test/java/org/apache/iceberg/rest/events/parsers/TestCreateNamespaceOperationParser.java:
##########
@@ -0,0 +1,131 @@
+/*
+ * 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.iceberg.rest.events.parsers;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static 
org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
+import static org.assertj.core.api.Assertions.assertThatNullPointerException;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import org.apache.iceberg.catalog.Namespace;
+import org.apache.iceberg.rest.events.operations.CreateNamespaceOperation;
+import 
org.apache.iceberg.rest.events.operations.ImmutableCreateNamespaceOperation;
+import org.junit.jupiter.api.Test;
+
+public class TestCreateNamespaceOperationParser {
+  @Test
+  void testToJson() {
+    CreateNamespaceOperation createNamespaceOperation =
+        
ImmutableCreateNamespaceOperation.builder().namespace(Namespace.of("a", 
"b")).build();
+    String createNamespaceOperationJson =
+        
"{\"operation-type\":\"create-namespace\",\"namespace\":[\"a\",\"b\"]}";
+
+    assertThat(CreateNamespaceOperationParser.toJson(createNamespaceOperation))
+        .isEqualTo(createNamespaceOperationJson);
+  }
+
+  @Test
+  void testToJsonPretty() {
+    CreateNamespaceOperation createNamespaceOperation =
+        
ImmutableCreateNamespaceOperation.builder().namespace(Namespace.of("a", 
"b")).build();
+    String createNamespaceOperationJson =
+        "{\n"
+            + "  \"operation-type\" : \"create-namespace\",\n"
+            + "  \"namespace\" : [ \"a\", \"b\" ]\n"
+            + "}";
+
+    
assertThat(CreateNamespaceOperationParser.toJsonPretty(createNamespaceOperation))
+        .isEqualTo(createNamespaceOperationJson);
+  }
+
+  @Test
+  void testToJsonWithNullOperation() {
+    assertThatNullPointerException()
+        .isThrownBy(() -> CreateNamespaceOperationParser.toJson(null))
+        .withMessage("Invalid create namespace operation: null");
+  }
+
+  @Test
+  void testToJsonWithOptionalProperties() {

Review Comment:
   Add round-trip serialization tests (fromJson(toJson(obj)) equals obj) for 
all parsers.



##########
core/src/main/java/org/apache/iceberg/rest/events/parsers/CreateNamespaceOperationParser.java:
##########
@@ -0,0 +1,83 @@
+/*
+ * 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.iceberg.rest.events.parsers;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonNode;
+import java.io.IOException;
+import java.util.Arrays;
+import org.apache.iceberg.catalog.Namespace;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+import org.apache.iceberg.rest.events.operations.CreateNamespaceOperation;
+import 
org.apache.iceberg.rest.events.operations.ImmutableCreateNamespaceOperation;
+import org.apache.iceberg.util.JsonUtil;
+
+public class CreateNamespaceOperationParser {

Review Comment:
   I thought @nastra suggested following the existing practice of putting the 
parser next to the object class in the same package, not a separate `parser` 
package.



##########
api/src/main/java/org/apache/iceberg/catalog/CatalogObjectIdentifier.java:
##########
@@ -0,0 +1,111 @@
+/*
+ * 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.iceberg.catalog;
+
+import java.util.Arrays;
+import java.util.function.Predicate;
+import java.util.regex.Pattern;
+import org.apache.iceberg.relocated.com.google.common.base.Joiner;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+
+/**
+ * Reference to a named object in a {@link Catalog}, such as {@link 
Namespace}, {@link
+ * org.apache.iceberg.Table}, or {@link org.apache.iceberg.view.View}.
+ */
+public class CatalogObjectIdentifier {

Review Comment:
   Should we update `Namespace` and `TableIdentifier` to extend from this class 
to reduce code duplication?



##########
core/src/main/java/org/apache/iceberg/rest/events/parsers/CustomOperationParser.java:
##########
@@ -0,0 +1,118 @@
+/*
+ * 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.iceberg.rest.events.parsers;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonNode;
+import java.io.IOException;
+import java.util.Arrays;
+import org.apache.iceberg.catalog.Namespace;
+import org.apache.iceberg.catalog.TableIdentifier;
+import org.apache.iceberg.catalog.TableIdentifierParser;
+import org.apache.iceberg.relocated.com.google.common.base.Preconditions;
+import org.apache.iceberg.rest.events.operations.CustomOperation;
+import org.apache.iceberg.rest.events.operations.ImmutableCustomOperation;
+import org.apache.iceberg.rest.events.operations.OperationType;
+import org.apache.iceberg.util.JsonUtil;
+
+public class CustomOperationParser {
+  private static final String OPERATION_TYPE = "operation-type";
+  private static final String CUSTOM_OPERATION_TYPE = "custom-type";
+  private static final String IDENTIFIER = "identifier";
+  private static final String NAMESPACE = "namespace";
+  private static final String TABLE_UUID = "table-uuid";
+  private static final String VIEW_UUID = "view-uuid";
+
+  private CustomOperationParser() {}
+
+  public static String toJson(CustomOperation operation) {
+    return toJson(operation, false);
+  }
+
+  public static String toJsonPretty(CustomOperation operation) {
+    return toJson(operation, true);
+  }
+
+  private static String toJson(CustomOperation operation, boolean pretty) {
+    return JsonUtil.generate(gen -> toJson(operation, gen), pretty);
+  }
+
+  public static void toJson(CustomOperation operation, JsonGenerator gen) 
throws IOException {
+    Preconditions.checkNotNull(operation, "Invalid custom operation: null");
+
+    gen.writeStartObject();
+
+    gen.writeStringField(OPERATION_TYPE, operation.operationType().type());
+    gen.writeStringField(CUSTOM_OPERATION_TYPE, 
operation.customOperationType().type());
+
+    if (operation.identifier() != null) {
+      gen.writeFieldName(IDENTIFIER);
+      TableIdentifierParser.toJson(operation.identifier(), gen);
+    }
+
+    if (operation.namespace() != null) {
+      JsonUtil.writeStringArray(NAMESPACE, 
Arrays.asList(operation.namespace().levels()), gen);
+    }
+
+    if (operation.tableUuid() != null) {
+      gen.writeStringField(TABLE_UUID, operation.tableUuid());
+    }
+
+    if (operation.viewUuid() != null) {
+      gen.writeStringField(VIEW_UUID, operation.viewUuid());
+    }
+
+    gen.writeEndObject();

Review Comment:
   it seems to silently drops `properties`



##########
core/src/main/java/org/apache/iceberg/rest/events/operations/CreateNamespaceOperation.java:
##########
@@ -0,0 +1,36 @@
+/*
+ * 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.iceberg.rest.events.operations;
+
+import java.util.Map;
+import org.apache.iceberg.catalog.Namespace;
+import org.immutables.value.Value;
+
[email protected]
+public interface CreateNamespaceOperation extends Operation {

Review Comment:
   should we group these tiny classes in a `CatalogOperations` class to reduce 
the number of classes?
   
   It seems like an existing practice, like `MetadataUpdate` class.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to