This is an automated email from the ASF dual-hosted git repository.
yashmayya pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 1f6b882841 Add withTableProperties to Get Tenant Table API (#16202)
1f6b882841 is described below
commit 1f6b8828411297c818cf0ba72dfa98c05a894b2d
Author: Jhow <[email protected]>
AuthorDate: Thu Jul 10 20:17:22 2025 -0700
Add withTableProperties to Get Tenant Table API (#16202)
---
.../api/resources/PinotTenantRestletResource.java | 38 ++++++--
.../tenant/TenantTableWithProperties.java | 103 +++++++++++++++++++++
2 files changed, 134 insertions(+), 7 deletions(-)
diff --git
a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTenantRestletResource.java
b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTenantRestletResource.java
index 19b9de65fc..94a1b125c1 100644
---
a/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTenantRestletResource.java
+++
b/pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTenantRestletResource.java
@@ -53,6 +53,7 @@ import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
+import org.apache.helix.model.IdealState;
import org.apache.helix.model.InstanceConfig;
import org.apache.pinot.common.assignment.InstancePartitions;
import org.apache.pinot.common.assignment.InstancePartitionsUtils;
@@ -70,6 +71,8 @@ import
org.apache.pinot.controller.helix.core.rebalance.tenant.TenantRebalanceCo
import
org.apache.pinot.controller.helix.core.rebalance.tenant.TenantRebalanceProgressStats;
import
org.apache.pinot.controller.helix.core.rebalance.tenant.TenantRebalanceResult;
import
org.apache.pinot.controller.helix.core.rebalance.tenant.TenantRebalancer;
+import
org.apache.pinot.controller.helix.core.rebalance.tenant.TenantTableWithProperties;
+import org.apache.pinot.controller.util.TableSizeReader;
import org.apache.pinot.core.auth.Actions;
import org.apache.pinot.core.auth.Authorize;
import org.apache.pinot.core.auth.TargetType;
@@ -126,6 +129,7 @@ public class PinotTenantRestletResource {
private static final Logger LOGGER =
LoggerFactory.getLogger(PinotTenantRestletResource.class);
private static final String TENANT_NAME = "tenantName";
private static final String TABLES = "tables";
+ public static final String TABLES_WITH_PROPERTIES = "tablesWithProperties";
@Inject
PinotHelixResourceManager _pinotHelixResourceManager;
@@ -136,6 +140,9 @@ public class PinotTenantRestletResource {
@Inject
TenantRebalancer _tenantRebalancer;
+ @Inject
+ TableSizeReader _tableSizeReader;
+
@POST
@Path("/tenants")
@Authorize(targetType = TargetType.CLUSTER, action =
Actions.Cluster.CREATE_TENANT)
@@ -295,9 +302,11 @@ public class PinotTenantRestletResource {
@ApiParam(value = "Tenant name", required = true)
@PathParam("tenantName") String tenantName,
@ApiParam(value = "Tenant type (server|broker)",
required = false, allowableValues = "BROKER, SERVER", defaultValue =
"SERVER")
- @QueryParam("type") String tenantType, @Context HttpHeaders headers) {
+ @QueryParam("type") String tenantType,
+ @QueryParam("withTableProperties") @DefaultValue("false") boolean
withTableProperties,
+ @Context HttpHeaders headers) {
if (tenantType == null || tenantType.isEmpty() ||
tenantType.equalsIgnoreCase("server")) {
- return getTablesServedFromServerTenant(tenantName,
headers.getHeaderString(DATABASE));
+ return getTablesServedFromServerTenant(tenantName,
headers.getHeaderString(DATABASE), withTableProperties);
} else if (tenantType.equalsIgnoreCase("broker")) {
return getTablesServedFromBrokerTenant(tenantName,
headers.getHeaderString(DATABASE));
} else {
@@ -386,23 +395,38 @@ public class PinotTenantRestletResource {
}
}
- private String getTablesServedFromServerTenant(String tenantName, @Nullable
String database) {
+ private String getTablesServedFromServerTenant(String tenantName, @Nullable
String database,
+ boolean withTableProperties) {
Set<String> tables = new HashSet<>();
+ Set<TenantTableWithProperties> tablePropertiesSet = withTableProperties ?
new HashSet<>() : null;
ObjectNode resourceGetRet = JsonUtils.newObjectNode();
- for (String table : _pinotHelixResourceManager.getAllTables(database)) {
- TableConfig tableConfig =
_pinotHelixResourceManager.getTableConfig(table);
+ for (String tableNameWithType :
_pinotHelixResourceManager.getAllTables(database)) {
+ TableConfig tableConfig =
_pinotHelixResourceManager.getTableConfig(tableNameWithType);
if (tableConfig == null) {
- LOGGER.error("Unable to retrieve table config for table: {}", table);
+ LOGGER.error("Unable to retrieve table config for table: {}",
tableNameWithType);
continue;
}
Set<String> relevantTags = TableConfigUtils.getRelevantTags(tableConfig);
if (relevantTags.contains(TagNameUtils.getServerTagForTenant(tenantName,
tableConfig.getTableType()))) {
- tables.add(table);
+ tables.add(tableNameWithType);
+ if (withTableProperties) {
+ IdealState idealState =
_pinotHelixResourceManager.getTableIdealState(tableNameWithType);
+ if (idealState == null) {
+ LOGGER.error("Unable to retrieve ideal state for table: {}",
tableNameWithType);
+ continue;
+ }
+ TenantTableWithProperties tableWithProperties = new
TenantTableWithProperties(tableConfig,
+ idealState.getRecord().getMapFields(), _tableSizeReader);
+ tablePropertiesSet.add(tableWithProperties);
+ }
}
}
resourceGetRet.set(TABLES, JsonUtils.objectToJsonNode(tables));
+ if (withTableProperties) {
+ resourceGetRet.set(TABLES_WITH_PROPERTIES,
JsonUtils.objectToJsonNode(tablePropertiesSet));
+ }
return resourceGetRet.toString();
}
diff --git
a/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/rebalance/tenant/TenantTableWithProperties.java
b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/rebalance/tenant/TenantTableWithProperties.java
new file mode 100644
index 0000000000..fd670d76a5
--- /dev/null
+++
b/pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/rebalance/tenant/TenantTableWithProperties.java
@@ -0,0 +1,103 @@
+/**
+ * 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.pinot.controller.helix.core.rebalance.tenant;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import java.util.Map;
+import org.apache.pinot.common.exception.InvalidConfigException;
+import org.apache.pinot.controller.util.TableSizeReader;
+import org.apache.pinot.spi.config.table.TableConfig;
+import org.apache.pinot.spi.config.table.TableType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Class to hold table properties when listing tables for a tenant during
rebalancing.
+ * This class contains pre-defined properties of a table that are relevant
+ * for making include/exclude decisions during tenant rebalance operations.
+ * The properties focus on factors that could impact rebalance performance and
stability.
+ */
+@JsonInclude(JsonInclude.Include.NON_NULL)
+public class TenantTableWithProperties {
+ // Basic table identification
+ private static final Logger LOGGER =
LoggerFactory.getLogger(TenantTableWithProperties.class);
+
+ @JsonProperty("tableNameWithType")
+ private final String _tableNameWithType;
+ @JsonProperty("tableType")
+ private final TableType _tableType;
+ @JsonProperty("isDimTable")
+ private final boolean _isDimTable;
+ @JsonProperty("replication")
+ private final int _replication;
+ @JsonProperty("totalSegments")
+ private final int _totalSegments;
+ @JsonProperty("estimatedTableSizeInBytes")
+ private final long _estimatedTableSizeInBytes;
+ @JsonProperty("isUpsertEnabled")
+ private final boolean _isUpsertEnabled;
+ @JsonProperty("isDedupEnabled")
+ private final boolean _isDedupEnabled;
+
+ private static final int TABLE_SIZE_READER_TIMEOUT_MS = 10000; // 10 seconds
+
+ @JsonCreator
+ public TenantTableWithProperties(
+ @JsonProperty("tableNameWithType") String tableNameWithType,
+ @JsonProperty("tableType") TableType tableType,
+ @JsonProperty("isDimTable") boolean isDimTable,
+ @JsonProperty("replication") int replication,
+ @JsonProperty("totalSegments") int totalSegments,
+ @JsonProperty("estimatedTableSizeInBytes") long
estimatedTableSizeInBytes,
+ @JsonProperty("isUpsertEnabled") boolean isUpsertEnabled,
+ @JsonProperty("isDedupEnabled") boolean isDedupEnabled) {
+ _tableNameWithType = tableNameWithType;
+ _tableType = tableType;
+ _isDimTable = isDimTable;
+ _replication = replication;
+ _totalSegments = totalSegments;
+ _estimatedTableSizeInBytes = estimatedTableSizeInBytes;
+ _isUpsertEnabled = isUpsertEnabled;
+ _isDedupEnabled = isDedupEnabled;
+ }
+
+ public TenantTableWithProperties(TableConfig tableConfig, Map<String,
Map<String, String>> idealStateInstanceStateMap,
+ TableSizeReader tableSizeReader) {
+ long estimatedTableSizeInBytes;
+ _tableNameWithType = tableConfig.getTableName();
+ _tableType = tableConfig.getTableType();
+ _isDimTable = tableConfig.isDimTable();
+ _replication = tableConfig.getReplication();
+ _totalSegments = idealStateInstanceStateMap.size();
+ try {
+ TableSizeReader.TableSubTypeSizeDetails sizeDetails =
+ tableSizeReader.getTableSubtypeSize(_tableNameWithType,
TABLE_SIZE_READER_TIMEOUT_MS, false);
+ estimatedTableSizeInBytes = sizeDetails._estimatedSizeInBytes;
+ } catch (InvalidConfigException e) {
+ LOGGER.warn("Failed to read table size for table: {}",
_tableNameWithType, e);
+ estimatedTableSizeInBytes = -1; // Indicate failure to read size
+ }
+ _estimatedTableSizeInBytes = estimatedTableSizeInBytes;
+ _isUpsertEnabled = tableConfig.isUpsertEnabled();
+ _isDedupEnabled = tableConfig.isDedupEnabled();
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]