Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ public static <T> T cloneIcebergRESTObject(Object message, Class<T> className) {
}
}

public static Map<String, Object> toSerializableMap(Object message) {
ObjectMapper icebergObjectMapper = IcebergObjectMapper.getInstance();
try {
byte[] values = icebergObjectMapper.writeValueAsBytes(message);
return icebergObjectMapper.readValue(values, Map.class);
Comment on lines +118 to +122
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

toSerializableMap is new behavior that changes listener payload shapes, but there’s no test coverage asserting that it actually produces a deep-cloned, serializable map (and not Iceberg model instances) for representative requests/responses. Consider adding a focused unit test (e.g., alongside the existing TestIcebergRESTUtils#testSerdeIcebergRESTObject) that validates the returned map structure and that mutations to the original object don’t affect the stored payload.

Copilot generated this review using guidance from repository custom instructions.
} catch (IOException e) {
Comment on lines +118 to +123
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

toSerializableMap deserializes with Map.class and returns it as Map<String, Object>, which relies on an unchecked conversion and loses type information. Consider using a TypeReference<Map<String, Object>> (or JavaType) to keep the method type-safe and avoid warnings/possible key-type surprises.

Copilot uses AI. Check for mistakes.
throw new RuntimeException(e);
}
}

public static NameIdentifier getGravitinoNameIdentifier(
String metalakeName, String catalogName, Namespace namespace) {
Stream<String> catalogNS =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,33 @@

package org.apache.gravitino.listener.api.event;

import java.util.Map;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.iceberg.service.IcebergRESTUtils;
import org.apache.iceberg.rest.requests.CreateNamespaceRequest;
import org.apache.iceberg.rest.responses.CreateNamespaceResponse;

/** Represent an event after creating Iceberg namespace successfully. */
@DeveloperApi
public class IcebergCreateNamespaceEvent extends IcebergNamespaceEvent {

private final CreateNamespaceRequest createNamespaceRequest;
private final CreateNamespaceResponse createNamespaceResponse;
private final Map<String, Object> createNamespaceRequest;
private final Map<String, Object> createNamespaceResponse;

public IcebergCreateNamespaceEvent(
IcebergRequestContext icebergRequestContext,
NameIdentifier nameIdentifier,
CreateNamespaceRequest createNamespaceRequest,
CreateNamespaceResponse createNamespaceResponse) {
Object createNamespaceRequest,
Object createNamespaceResponse) {
super(icebergRequestContext, nameIdentifier);
this.createNamespaceRequest =
IcebergRESTUtils.cloneIcebergRESTObject(
createNamespaceRequest, CreateNamespaceRequest.class);
this.createNamespaceResponse =
IcebergRESTUtils.cloneIcebergRESTObject(
createNamespaceResponse, CreateNamespaceResponse.class);
this.createNamespaceRequest = IcebergRESTUtils.toSerializableMap(createNamespaceRequest);
this.createNamespaceResponse = IcebergRESTUtils.toSerializableMap(createNamespaceResponse);
}

public CreateNamespaceRequest createNamespaceRequest() {
public Map<String, Object> createNamespaceRequest() {
return createNamespaceRequest;
}

public CreateNamespaceResponse createNamespaceResponse() {
public Map<String, Object> createNamespaceResponse() {
return createNamespaceResponse;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,26 @@

package org.apache.gravitino.listener.api.event;

import java.util.Map;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.iceberg.service.IcebergRESTUtils;
import org.apache.iceberg.rest.requests.CreateNamespaceRequest;

/** Represent a failure event when creating Iceberg namespace failed. */
@DeveloperApi
public class IcebergCreateNamespaceFailureEvent extends IcebergNamespaceFailureEvent {
private final CreateNamespaceRequest createNamespaceRequest;
private final Map<String, Object> createNamespaceRequest;

public IcebergCreateNamespaceFailureEvent(
IcebergRequestContext icebergRequestContext,
NameIdentifier nameIdentifier,
CreateNamespaceRequest createNamespaceRequest,
Object createNamespaceRequest,
Exception e) {
super(icebergRequestContext, nameIdentifier, e);
this.createNamespaceRequest =
IcebergRESTUtils.cloneIcebergRESTObject(
createNamespaceRequest, CreateNamespaceRequest.class);
this.createNamespaceRequest = IcebergRESTUtils.toSerializableMap(createNamespaceRequest);
}

public CreateNamespaceRequest createNamespaceRequest() {
public Map<String, Object> createNamespaceRequest() {
return createNamespaceRequest;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,41 +19,38 @@

package org.apache.gravitino.listener.api.event;

import java.util.Map;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.iceberg.service.IcebergRESTUtils;
import org.apache.iceberg.rest.requests.CreateTableRequest;
import org.apache.iceberg.rest.responses.LoadTableResponse;

/** Represent an event after creating Iceberg table successfully. */
@DeveloperApi
public class IcebergCreateTableEvent extends IcebergTableEvent {

private final CreateTableRequest createTableRequest;
private final LoadTableResponse loadTableResponse;
private final Map<String, Object> createTableRequest;
private final Map<String, Object> loadTableResponse;

public IcebergCreateTableEvent(
IcebergRequestContext icebergRequestContext,
NameIdentifier resourceIdentifier,
CreateTableRequest createTableRequest,
LoadTableResponse loadTableResponse) {
Object createTableRequest,
Object loadTableResponse) {
super(icebergRequestContext, resourceIdentifier);
this.createTableRequest =
IcebergRESTUtils.cloneIcebergRESTObject(createTableRequest, CreateTableRequest.class);
this.loadTableResponse =
IcebergRESTUtils.cloneIcebergRESTObject(loadTableResponse, LoadTableResponse.class);
this.createTableRequest = IcebergRESTUtils.toSerializableMap(createTableRequest);
this.loadTableResponse = IcebergRESTUtils.toSerializableMap(loadTableResponse);
}

@Override
public OperationType operationType() {
return OperationType.CREATE_TABLE;
}

public CreateTableRequest createTableRequest() {
public Map<String, Object> createTableRequest() {
return createTableRequest;
}

public LoadTableResponse loadTableResponse() {
public Map<String, Object> loadTableResponse() {
return loadTableResponse;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,31 @@

package org.apache.gravitino.listener.api.event;

import java.util.Map;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.iceberg.service.IcebergRESTUtils;
import org.apache.iceberg.rest.requests.CreateTableRequest;

/** Represent a failure event when creating Iceberg table failed. */
@DeveloperApi
public class IcebergCreateTableFailureEvent extends IcebergTableFailureEvent {
private final CreateTableRequest createTableRequest;
private final Map<String, Object> createTableRequest;

public IcebergCreateTableFailureEvent(
IcebergRequestContext icebergRequestContext,
NameIdentifier nameIdentifier,
CreateTableRequest createTableRequest,
Object createTableRequest,
Exception e) {
super(icebergRequestContext, nameIdentifier, e);
this.createTableRequest =
IcebergRESTUtils.cloneIcebergRESTObject(createTableRequest, CreateTableRequest.class);
this.createTableRequest = IcebergRESTUtils.toSerializableMap(createTableRequest);
}

@Override
public OperationType operationType() {
return OperationType.CREATE_TABLE;
}

public CreateTableRequest createTableRequest() {
public Map<String, Object> createTableRequest() {
return createTableRequest;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,36 +19,33 @@

package org.apache.gravitino.listener.api.event;

import java.util.Map;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.iceberg.service.IcebergRESTUtils;
import org.apache.iceberg.rest.requests.CreateViewRequest;
import org.apache.iceberg.rest.responses.LoadViewResponse;

/** Represent an event after creating Iceberg view successfully. */
@DeveloperApi
public class IcebergCreateViewEvent extends IcebergViewEvent {

private final CreateViewRequest createViewRequest;
private final LoadViewResponse loadViewResponse;
private final Map<String, Object> createViewRequest;
private final Map<String, Object> loadViewResponse;

public IcebergCreateViewEvent(
IcebergRequestContext icebergRequestContext,
NameIdentifier viewIdentifier,
CreateViewRequest createViewRequest,
LoadViewResponse loadViewResponse) {
Object createViewRequest,
Object loadViewResponse) {
super(icebergRequestContext, viewIdentifier);
this.createViewRequest =
IcebergRESTUtils.cloneIcebergRESTObject(createViewRequest, CreateViewRequest.class);
this.loadViewResponse =
IcebergRESTUtils.cloneIcebergRESTObject(loadViewResponse, LoadViewResponse.class);
this.createViewRequest = IcebergRESTUtils.toSerializableMap(createViewRequest);
this.loadViewResponse = IcebergRESTUtils.toSerializableMap(loadViewResponse);
}

public CreateViewRequest createViewRequest() {
public Map<String, Object> createViewRequest() {
return createViewRequest;
}

public LoadViewResponse loadViewResponse() {
public Map<String, Object> loadViewResponse() {
return loadViewResponse;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,26 @@

package org.apache.gravitino.listener.api.event;

import java.util.Map;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.iceberg.service.IcebergRESTUtils;
import org.apache.iceberg.rest.requests.CreateViewRequest;

/** Represent a failure event when creating Iceberg view failed. */
@DeveloperApi
public class IcebergCreateViewFailureEvent extends IcebergViewFailureEvent {
private final CreateViewRequest createViewRequest;
private final Map<String, Object> createViewRequest;

public IcebergCreateViewFailureEvent(
IcebergRequestContext icebergRequestContext,
NameIdentifier viewIdentifier,
CreateViewRequest createViewRequest,
Object createViewRequest,
Exception e) {
super(icebergRequestContext, viewIdentifier, e);
this.createViewRequest =
IcebergRESTUtils.cloneIcebergRESTObject(createViewRequest, CreateViewRequest.class);
this.createViewRequest = IcebergRESTUtils.toSerializableMap(createViewRequest);
}

public CreateViewRequest createViewRequest() {
public Map<String, Object> createViewRequest() {
return createViewRequest;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,25 @@

package org.apache.gravitino.listener.api.event;

import java.util.Map;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.iceberg.service.IcebergRESTUtils;
import org.apache.iceberg.rest.responses.GetNamespaceResponse;

/** Represent an event after loading Iceberg namespace successfully. */
@DeveloperApi
public class IcebergLoadNamespaceEvent extends IcebergNamespaceEvent {
private final GetNamespaceResponse getNamespaceResponse;
private final Map<String, Object> getNamespaceResponse;

public IcebergLoadNamespaceEvent(
IcebergRequestContext icebergRequestContext,
NameIdentifier nameIdentifier,
GetNamespaceResponse getNamespaceResponse) {
Object getNamespaceResponse) {
super(icebergRequestContext, nameIdentifier);
this.getNamespaceResponse =
IcebergRESTUtils.cloneIcebergRESTObject(getNamespaceResponse, GetNamespaceResponse.class);
this.getNamespaceResponse = IcebergRESTUtils.toSerializableMap(getNamespaceResponse);
}

public GetNamespaceResponse getNamespaceResponse() {
public Map<String, Object> getNamespaceResponse() {
return getNamespaceResponse;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,30 @@

package org.apache.gravitino.listener.api.event;

import java.util.Map;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.iceberg.service.IcebergRESTUtils;
import org.apache.iceberg.rest.responses.LoadTableResponse;

/** Represent an event after loading Iceberg table successfully. */
@DeveloperApi
public class IcebergLoadTableEvent extends IcebergTableEvent {
private final LoadTableResponse loadTableResponse;
private final Map<String, Object> loadTableResponse;

public IcebergLoadTableEvent(
IcebergRequestContext icebergRequestContext,
NameIdentifier resourceIdentifier,
LoadTableResponse loadTableResponse) {
Object loadTableResponse) {
super(icebergRequestContext, resourceIdentifier);
this.loadTableResponse =
IcebergRESTUtils.cloneIcebergRESTObject(loadTableResponse, LoadTableResponse.class);
this.loadTableResponse = IcebergRESTUtils.toSerializableMap(loadTableResponse);
}

@Override
public OperationType operationType() {
return OperationType.LOAD_TABLE;
}

public LoadTableResponse loadTableResponse() {
public Map<String, Object> loadTableResponse() {
return loadTableResponse;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,25 @@

package org.apache.gravitino.listener.api.event;

import java.util.Map;
import org.apache.gravitino.NameIdentifier;
import org.apache.gravitino.annotation.DeveloperApi;
import org.apache.gravitino.iceberg.service.IcebergRESTUtils;
import org.apache.iceberg.rest.responses.LoadViewResponse;

/** Represent an event after loading Iceberg view successfully. */
@DeveloperApi
public class IcebergLoadViewEvent extends IcebergViewEvent {
private final LoadViewResponse loadViewResponse;
private final Map<String, Object> loadViewResponse;

public IcebergLoadViewEvent(
IcebergRequestContext icebergRequestContext,
NameIdentifier viewIdentifier,
LoadViewResponse loadViewResponse) {
Object loadViewResponse) {
super(icebergRequestContext, viewIdentifier);
this.loadViewResponse =
IcebergRESTUtils.cloneIcebergRESTObject(loadViewResponse, LoadViewResponse.class);
this.loadViewResponse = IcebergRESTUtils.toSerializableMap(loadViewResponse);
}

public LoadViewResponse loadViewResponse() {
public Map<String, Object> loadViewResponse() {
return loadViewResponse;
}

Expand Down
Loading
Loading