Jackie-Jiang commented on a change in pull request #8188:
URL: https://github.com/apache/pinot/pull/8188#discussion_r810276532



##########
File path: 
pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableInstances.java
##########
@@ -51,8 +53,7 @@
   @Produces(MediaType.APPLICATION_JSON)
   @ApiOperation(value = "List table instances", notes = "List instances of the 
given table")
   @ApiResponses(value = {
-      @ApiResponse(code = 200, message = "Success"),
-      @ApiResponse(code = 404, message = "Table not found"),
+      @ApiResponse(code = 200, message = "Success"), @ApiResponse(code = 404, 
message = "Table not found"),

Review comment:
       revert this

##########
File path: 
pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java
##########
@@ -3180,12 +3180,56 @@ public TableStats getTableStats(String 
tableNameWithType) {
     return new TableStats(creationTime);
   }
 
+  /**
+   * Return the list of live brokers serving the corresponding table. Based on 
the
+   * input tableName, there can be 3 cases:
+   *
+   * 1. If the tableName has a type-suffix, then brokers for only that 
table-type
+   *    will be returned.
+   * 2. If the tableName doesn't have a type-suffix and there's only 1 type 
for that
+   *    table, then the brokers for that table-type would be returned.
+   * 3. If the tableName doesn't have a type-suffix and there are both REALTIME
+   *    and OFFLINE tables, then the intersection of the brokers for the two 
table-types
+   *    would be returned. Intersection is taken since the method guarantees 
to return
+   *    brokers which can serve the given table. In case of no type provided, 
it returns
+   *    broker which can serve both table-types.
+   *
+   * @param tableName name of table with or without type suffix.
+   * @return list of brokers serving the given table in the format: 
Broker_hostname_port.
+   * @throws TableNotFoundException when no table exists with the given name.
+   */
+  public List<String> getLiveBrokersForTable(String tableName)
+      throws TableNotFoundException {
+    TableType inputTableType = 
TableNameBuilder.getTableTypeFromTableName(tableName);
+    if (inputTableType != null) {
+      if (!hasTable(tableName)) {
+        throw new TableNotFoundException(String.format("Table=%s not found", 
tableName));
+      }
+      return getLiveBrokersForTable(tableName, inputTableType);
+    }
+    boolean hasOfflineTable = hasOfflineTable(tableName);

Review comment:
       (minor) Generate `offlineTableName` and `realtimeTableName` using 
`TableNameBuilder.OFFLINE.tableNameWithType(tableName)` and 
`TableNameBuilder.REALTIME.tableNameWithType(tableName)` which can be used to 
check table existence and lookup the external view to avoid generating them 
multiple times.

##########
File path: 
pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java
##########
@@ -3180,12 +3180,56 @@ public TableStats getTableStats(String 
tableNameWithType) {
     return new TableStats(creationTime);
   }
 
+  /**
+   * Return the list of live brokers serving the corresponding table. Based on 
the

Review comment:
       +1, very good documentation

##########
File path: 
pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableInstances.java
##########
@@ -116,16 +117,25 @@ public String getTableInstances(
   }
 
   @GET
-  @Path("/tables/{tableNameWithType}/livebrokers")
+  @Path("/tables/{tableName}/livebrokers")
   @Produces(MediaType.APPLICATION_JSON)
   @ApiOperation(value = "List the brokers serving a table", notes = "List live 
brokers of the given table based on EV")
   @ApiResponses(value = {
       @ApiResponse(code = 200, message = "Success"),
       @ApiResponse(code = 404, message = "Table not found"),
-      @ApiResponse(code = 500, message = "Internal server error")})
+      @ApiResponse(code = 500, message = "Internal server error")
+  })
   public List<String> getLiveBrokersForTable(
-      @ApiParam(value = "Table name with type", required = true)
-      @PathParam("tableNameWithType") String tableNameWithType) {
-    return 
_pinotHelixResourceManager.getLiveBrokersForTable(tableNameWithType);
+      @ApiParam(value = "Table name (with or without type)", required = true)
+      @PathParam("tableName") String tableName) {
+    try {
+      return _pinotHelixResourceManager.getLiveBrokersForTable(tableName);
+    } catch (TableNotFoundException tableNotFoundException) {
+      throw new WebApplicationException(String.format("Table=%s not found", 
tableName), 404);

Review comment:
       We have some example of returning table not found in 
`PinotTableRestletResource`
   ```suggestion
         throw new ControllerApplicationException(LOGGER, String.format("Table 
'%s' does not exist", tableName),
               Response.Status.NOT_FOUND);
   ```

##########
File path: 
pinot-controller/src/main/java/org/apache/pinot/controller/api/resources/PinotTableInstances.java
##########
@@ -116,16 +117,25 @@ public String getTableInstances(
   }
 
   @GET
-  @Path("/tables/{tableNameWithType}/livebrokers")
+  @Path("/tables/{tableName}/livebrokers")
   @Produces(MediaType.APPLICATION_JSON)
   @ApiOperation(value = "List the brokers serving a table", notes = "List live 
brokers of the given table based on EV")
   @ApiResponses(value = {
       @ApiResponse(code = 200, message = "Success"),
       @ApiResponse(code = 404, message = "Table not found"),
-      @ApiResponse(code = 500, message = "Internal server error")})
+      @ApiResponse(code = 500, message = "Internal server error")
+  })
   public List<String> getLiveBrokersForTable(
-      @ApiParam(value = "Table name with type", required = true)
-      @PathParam("tableNameWithType") String tableNameWithType) {
-    return 
_pinotHelixResourceManager.getLiveBrokersForTable(tableNameWithType);
+      @ApiParam(value = "Table name (with or without type)", required = true)
+      @PathParam("tableName") String tableName) {
+    try {
+      return _pinotHelixResourceManager.getLiveBrokersForTable(tableName);
+    } catch (TableNotFoundException tableNotFoundException) {
+      throw new WebApplicationException(String.format("Table=%s not found", 
tableName), 404);
+    }
+  }
+
+  public void setPinotHelixResourceManager(PinotHelixResourceManager 
pinotHelixResourceManager) {

Review comment:
       Suggest removing this function and `PinotTableInstancesTest`. The test 
in `PinotHelixResourceManagerTest` is good enough, no need to mock a 
`PinotHelixResourceManager` for one line of code

##########
File path: 
pinot-controller/src/test/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManagerTest.java
##########
@@ -939,6 +940,20 @@ public void testGetLiveBrokersForTable()
     for (String broker: liveBrokersForTable) {
       Assert.assertTrue(broker.startsWith("Broker_localhost"));
     }
+
+    // Test retrieving the live broker for table without table-type suffix.
+    liveBrokersForTable =
+        
ControllerTestUtils.getHelixResourceManager().getLiveBrokersForTable(TABLE_NAME);
+    Assert.assertEquals(liveBrokersForTable.size(), 2);
+
+    // Test retrieving the live broker for table with non-existent table-type.
+    try {
+      
ControllerTestUtils.getHelixResourceManager().getLiveBrokersForTable(REALTIME_TABLE_NAME);
+      Assert.fail("Method call above should have failed");
+    } catch (TableNotFoundException tableNotFoundException) {
+      
Assert.assertTrue(tableNotFoundException.getMessage().contains(REALTIME_TABLE_NAME));
+    }
+

Review comment:
       Shall we add a test for cases where both OFFLINE and REALTIME table 
exist, or none of them exist?

##########
File path: 
pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/PinotHelixResourceManager.java
##########
@@ -3180,12 +3180,56 @@ public TableStats getTableStats(String 
tableNameWithType) {
     return new TableStats(creationTime);
   }
 
+  /**
+   * Return the list of live brokers serving the corresponding table. Based on 
the
+   * input tableName, there can be 3 cases:
+   *
+   * 1. If the tableName has a type-suffix, then brokers for only that 
table-type
+   *    will be returned.
+   * 2. If the tableName doesn't have a type-suffix and there's only 1 type 
for that
+   *    table, then the brokers for that table-type would be returned.
+   * 3. If the tableName doesn't have a type-suffix and there are both REALTIME
+   *    and OFFLINE tables, then the intersection of the brokers for the two 
table-types
+   *    would be returned. Intersection is taken since the method guarantees 
to return
+   *    brokers which can serve the given table. In case of no type provided, 
it returns
+   *    broker which can serve both table-types.
+   *
+   * @param tableName name of table with or without type suffix.
+   * @return list of brokers serving the given table in the format: 
Broker_hostname_port.
+   * @throws TableNotFoundException when no table exists with the given name.
+   */
+  public List<String> getLiveBrokersForTable(String tableName)
+      throws TableNotFoundException {
+    TableType inputTableType = 
TableNameBuilder.getTableTypeFromTableName(tableName);
+    if (inputTableType != null) {
+      if (!hasTable(tableName)) {
+        throw new TableNotFoundException(String.format("Table=%s not found", 
tableName));
+      }
+      return getLiveBrokersForTable(tableName, inputTableType);
+    }
+    boolean hasOfflineTable = hasOfflineTable(tableName);
+    boolean hasRealtimeTable = hasRealtimeTable(tableName);
+    if (!hasOfflineTable && !hasRealtimeTable) {
+      throw new TableNotFoundException(String.format("Table=%s not found", 
tableName));
+    }
+    if (hasOfflineTable && hasRealtimeTable) {
+      Set<String> offlineTables = new 
HashSet<>(getLiveBrokersForTable(tableName, TableType.OFFLINE));
+      return getLiveBrokersForTable(tableName, TableType.REALTIME).stream()
+          .filter(offlineTables::contains)
+          .collect(Collectors.toList());
+    } else {
+      return getLiveBrokersForTable(tableName, hasOfflineTable ? 
TableType.OFFLINE : TableType.REALTIME);
+    }
+  }
+
   /**
    * Return the list of live brokers serving the corresponding table.
    *  Each entry in the broker list is of the following format:
    *  Broker_hostname_port
    */
-  public List<String> getLiveBrokersForTable(String tableNameWithType) {
+  public List<String> getLiveBrokersForTable(String tableName, TableType 
tableType) {

Review comment:
       Suggest merging the logic of this method into the main method to avoid 
looking up `BROKER_RESOURCE` twice. Also (not introduced in this PR), when 
`BROKER_RESOURCE` cannot be found, we should probably throw an exception 
instead of returning empty result




-- 
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