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

bankim pushed a commit to branch branch-1.15.x
in repository https://gitbox.apache.org/repos/asf/kudu.git

commit a5bf0e7130c927d350a57c54213958dcb90d40a8
Author: Abhishek Chennaka <[email protected]>
AuthorDate: Wed May 26 16:16:52 2021 -0400

    [java] KUDU-3267 Improve logging on writes to non-existent partitions
    
    This patch helps to log a more meaningful error message when a
    non-existent range partition is written to by the Kudu Java client.
    Due to different behavior of the client in different flush modes,
    the existing messages returned by the client are different when
    different flush modes are used. Effort has been made to bring
    consistency to the error messages returned in all the flush modes
    as well.
    
    For example in the default AUTO_FLUSH_BACKGROUND mode
    Existing log message snippet:
    Not found: ([0x000000018005BDAA4BF52400, 0x000000028005BCC2F4C85400))
    New log message snippet (in any FLUSH mode):
    Not Found: accessed range partition ([0x80000064, 0x800000C8)) does
    not exist in table: TestKuduSession
    
    Thanks to Grant Henke for the help in writing this patch.
    
    Change-Id: Ia24582de6b060e908f5ecbc46e2638b95cd567b3
    Reviewed-on: http://gerrit.cloudera.org:8080/17518
    Tested-by: Alexey Serbin <[email protected]>
    Reviewed-by: Alexey Serbin <[email protected]>
    (cherry picked from commit cae3ec8df5037f560defe5b121f197f27c7065f1)
    Reviewed-on: http://gerrit.cloudera.org:8080/17535
    Reviewed-by: Bankim Bhavsar <[email protected]>
    Tested-by: Kudu Jenkins
---
 .../org/apache/kudu/client/AsyncKuduSession.java   | 14 ++++++---
 .../kudu/client/NonCoveredRangeException.java      | 20 +++++++-----
 .../apache/kudu/client/TestKuduPartitioner.java    |  2 +-
 .../org/apache/kudu/client/TestKuduSession.java    | 36 ++++++++++++++++++++++
 4 files changed, 59 insertions(+), 13 deletions(-)

diff --git 
a/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduSession.java 
b/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduSession.java
index 3b0f5c0..0739733 100644
--- 
a/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduSession.java
+++ 
b/java/kudu-client/src/main/java/org/apache/kudu/client/AsyncKuduSession.java
@@ -370,7 +370,8 @@ public class AsyncKuduSession implements 
SessionConfiguration {
           if (failure instanceof NonCoveredRangeException) {
             // TODO: this should be something different than NotFound so that
             // applications can distinguish from updates on missing rows.
-            error = new RowError(Status.NotFound(failure.getMessage()), 
operation);
+            error = new RowError(Status.NotFound(String.format(
+                    "%s: %s", failure.getMessage(), 
operation.getTable().getName())), operation);
           } else {
             LOG.warn("unexpected tablet lookup failure for operation {}", 
operation, failure);
             error = new RowError(Status.RuntimeError(failure.getMessage()), 
operation);
@@ -808,9 +809,14 @@ public class AsyncKuduSession implements 
SessionConfiguration {
     @Override
     public Object call(Exception e) throws Exception {
       if (e instanceof KuduException) {
-        Status status = ((KuduException) e).getStatus();
-        RowError rowError = new RowError(status, operation);
-        return new OperationResponse(0, null, 0, operation, rowError);
+        Status status;
+        if (e instanceof NonCoveredRangeException) {
+          status = Status.NotFound(String.format(
+                  "%s: %s", e.getMessage(), operation.getTable().getName()));
+        } else {
+          status = ((KuduException) e).getStatus();
+        }
+        return new OperationResponse(0, null, 0, operation, new 
RowError(status, operation));
       }
       return e;
     }
diff --git 
a/java/kudu-client/src/main/java/org/apache/kudu/client/NonCoveredRangeException.java
 
b/java/kudu-client/src/main/java/org/apache/kudu/client/NonCoveredRangeException.java
index 6f3efe2..8d7640b 100644
--- 
a/java/kudu-client/src/main/java/org/apache/kudu/client/NonCoveredRangeException.java
+++ 
b/java/kudu-client/src/main/java/org/apache/kudu/client/NonCoveredRangeException.java
@@ -28,11 +28,22 @@ public class NonCoveredRangeException extends 
NonRecoverableException {
   private final byte[] nonCoveredRangeEnd;
 
   public NonCoveredRangeException(byte[] nonCoveredRangeStart, byte[] 
nonCoveredRangeEnd) {
-    super(Status.NotFound("non-covered range"));
+    super(Status.NotFound(getMessage(nonCoveredRangeStart, 
nonCoveredRangeEnd)));
     this.nonCoveredRangeStart = nonCoveredRangeStart;
     this.nonCoveredRangeEnd = nonCoveredRangeEnd;
   }
 
+  private static String getMessage(byte[] rangeStart, byte[] rangeEnd) {
+    return String.format("accessed range partition ([%s, %s)) does not exist 
in table",
+            rangeStart.length == 0 ? "<start>" : Bytes.hex(rangeStart),
+            rangeEnd.length == 0 ? "<end>" : Bytes.hex(rangeEnd));
+  }
+
+  @Override
+  public String getMessage() {
+    return getMessage(nonCoveredRangeStart, nonCoveredRangeEnd);
+  }
+
   byte[] getNonCoveredRangeStart() {
     return nonCoveredRangeStart;
   }
@@ -40,11 +51,4 @@ public class NonCoveredRangeException extends 
NonRecoverableException {
   byte[] getNonCoveredRangeEnd() {
     return nonCoveredRangeEnd;
   }
-
-  @Override
-  public String getMessage() {
-    return String.format("([%s, %s))",
-        nonCoveredRangeStart.length == 0 ? "<start>" : 
Bytes.hex(nonCoveredRangeStart),
-        nonCoveredRangeEnd.length == 0 ? "<end>" : 
Bytes.hex(nonCoveredRangeEnd));
-  }
 }
diff --git 
a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduPartitioner.java
 
b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduPartitioner.java
index 29bd3ed..6c5c063 100644
--- 
a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduPartitioner.java
+++ 
b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduPartitioner.java
@@ -158,7 +158,7 @@ public class TestKuduPartitioner {
       part.partitionRow(over);
       fail("partitionRow did not throw a NonCoveredRangeException");
     } catch (NonCoveredRangeException ex) {
-      // Expected
+      assertTrue(ex.getMessage().contains("does not exist in table"));
     }
   }
 
diff --git 
a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduSession.java 
b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduSession.java
index 52e2571..062fc67 100644
--- a/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduSession.java
+++ b/java/kudu-client/src/test/java/org/apache/kudu/client/TestKuduSession.java
@@ -540,6 +540,42 @@ public class TestKuduSession {
   }
 
   @Test(timeout = 10000)
+  public void testNonCoveredRangeException() throws Exception {
+    CreateTableOptions createOptions = 
getBasicTableOptionsWithNonCoveredRange();
+    createOptions.setNumReplicas(1);
+    client.createTable(tableName, basicSchema, createOptions);
+    KuduTable table = client.openTable(tableName);
+    Insert insert = createInsert(table, 150);
+
+    //AUTO_FLUSH_SYNC case
+    KuduSession session = client.newSession();
+    session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_SYNC);
+    OperationResponse apply = session.apply(insert);
+    assertTrue(apply.hasRowError());
+    System.err.println(apply.getRowError().getErrorStatus().getMessage());
+    assertTrue(apply.getRowError().getErrorStatus().getMessage().contains(
+            "does not exist in table: TestKuduSession"));
+    //AUTO_FLUSH_BACKGROUND case
+    session.setFlushMode(SessionConfiguration.FlushMode.AUTO_FLUSH_BACKGROUND);
+    assertEquals(null, session.apply(insert));
+    List<OperationResponse> autoFlushResult = session.flush();
+    assertEquals(1, autoFlushResult.size());
+    OperationResponse responseAuto = autoFlushResult.get(0);
+    assertTrue(responseAuto.hasRowError());
+    
assertTrue(responseAuto.getRowError().getErrorStatus().getMessage().contains(
+            "does not exist in table: TestKuduSession"));
+    //MANUAL_FLUSH case
+    session.setFlushMode(SessionConfiguration.FlushMode.MANUAL_FLUSH);
+    assertEquals(null, session.apply(insert));
+    List<OperationResponse> manualFlushResult = session.flush();
+    assertEquals(1, manualFlushResult.size());
+    OperationResponse responseManual = manualFlushResult.get(0);
+    assertTrue(responseManual.hasRowError());
+    
assertTrue(responseManual.getRowError().getErrorStatus().getMessage().contains(
+            "does not exist in table: TestKuduSession"));
+  }
+
+  @Test(timeout = 10000)
   public void testInsertAutoFlushSyncNonCoveredRange() throws Exception {
     CreateTableOptions createOptions = 
getBasicTableOptionsWithNonCoveredRange();
     createOptions.setNumReplicas(1);

Reply via email to