Repository: lens
Updated Branches:
  refs/heads/master f4da1f0b1 -> 9b402aee3


LENS-1242 : Fix JDBCDriver cancel query to call statement.cancel


Project: http://git-wip-us.apache.org/repos/asf/lens/repo
Commit: http://git-wip-us.apache.org/repos/asf/lens/commit/9b402aee
Tree: http://git-wip-us.apache.org/repos/asf/lens/tree/9b402aee
Diff: http://git-wip-us.apache.org/repos/asf/lens/diff/9b402aee

Branch: refs/heads/master
Commit: 9b402aee35e52fcf235974429cee760883b42271
Parents: f4da1f0
Author: Amareshwari Sriramadasu <[email protected]>
Authored: Fri Jul 29 18:07:28 2016 +0530
Committer: Puneet <[email protected]>
Committed: Fri Jul 29 18:07:28 2016 +0530

----------------------------------------------------------------------
 .../org/apache/lens/driver/jdbc/JDBCDriver.java | 28 +++++++-
 .../driver/jdbc/JDBCDriverConfConstants.java    |  3 +
 .../src/main/resources/jdbcdriver-default.xml   |  7 ++
 .../apache/lens/driver/jdbc/TestJdbcDriver.java | 68 +++++++++++++++-----
 .../drivers/jdbc/jdbc1/jdbcdriver-site.xml      |  3 +-
 src/site/apt/admin/jdbcdriver-config.apt        |  6 +-
 6 files changed, 95 insertions(+), 20 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lens/blob/9b402aee/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriver.java
----------------------------------------------------------------------
diff --git 
a/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriver.java 
b/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriver.java
index 8047302..15a1826 100644
--- a/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriver.java
+++ b/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriver.java
@@ -112,6 +112,7 @@ public class JDBCDriver extends AbstractLensDriver {
   private ImmutableSet<QueryLaunchingConstraint> queryConstraints;
   private ImmutableSet<WaitingQueriesSelectionPolicy> selectionPolicies;
 
+  private boolean isStatementCancelSupported;
   /**
    * Data related to a query submitted to JDBCDriver.
    */
@@ -209,6 +210,29 @@ public class JDBCDriver extends AbstractLensDriver {
       isClosed = true;
     }
 
+    public boolean cancel() {
+      boolean ret;
+      log.debug("Canceling resultFuture object");
+      ret = resultFuture.cancel(true);
+      log.debug("Done resultFuture cancel!");
+      // queryResult object would be null if query is not yet launched - since 
we did future.cancel, no other cancel is
+      // required.
+      if (queryResult != null && isStatementCancelSupported) {
+        log.debug("Cancelling query through statement cancel");
+        try {
+          queryResult.stmt.cancel();
+          log.debug("Done statement cancel!");
+          ret = true;
+        } catch (SQLFeatureNotSupportedException se) {
+          log.warn("Statement cancel not supported", se);
+        } catch(SQLException e) {
+          log.warn("Statement cancel failed", e);
+          ret = false;
+        }
+      }
+      return ret;
+    }
+
     public String getQueryHandleString() {
       return this.lensContext.getQueryHandleString();
     }
@@ -484,6 +508,7 @@ public class JDBCDriver extends AbstractLensDriver {
     this.logSegregationContext = new MappedDiagnosticLogSegregationContext();
     this.queryConstraints = 
getImplementations(QUERY_LAUNCHING_CONSTRAINT_FACTORIES_KEY, this.conf);
     this.selectionPolicies = 
getImplementations(WAITING_QUERIES_SELECTION_POLICY_FACTORIES_KEY, this.conf);
+    this.isStatementCancelSupported = 
conf.getBoolean(STATEMENT_CANCEL_SUPPORTED, DEFAULT_STATEMENT_CANCEL_SUPPORTED);
   }
 
   /**
@@ -1045,7 +1070,8 @@ public class JDBCDriver extends AbstractLensDriver {
   public boolean cancelQuery(QueryHandle handle) throws LensException {
     checkConfigured();
     JdbcQueryContext context = getQueryContext(handle);
-    boolean cancelResult = context.getResultFuture().cancel(true);
+    log.info("{} cancel request on query {}", getFullyQualifiedName(), handle);
+    boolean cancelResult = context.cancel();
     if (cancelResult) {
       context.setCancelled(true);
       // this is required because future.cancel does not guarantee

http://git-wip-us.apache.org/repos/asf/lens/blob/9b402aee/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriverConfConstants.java
----------------------------------------------------------------------
diff --git 
a/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriverConfConstants.java
 
b/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriverConfConstants.java
index ac0682d..3c34eb1 100644
--- 
a/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriverConfConstants.java
+++ 
b/lens-driver-jdbc/src/main/java/org/apache/lens/driver/jdbc/JDBCDriverConfConstants.java
@@ -110,4 +110,7 @@ public final class JDBCDriverConfConstants {
   public static final String WAITING_QUERIES_SELECTION_POLICY_FACTORIES_KEY = 
JDBC_DRIVER_PFX
     + "waiting.queries.selection.policy.factories";
   public static final String REGEX_REPLACEMENT_VALUES = JDBC_DRIVER_PFX + 
"regex.replacement.values";
+  public static final String STATEMENT_CANCEL_SUPPORTED = JDBC_DRIVER_PFX + 
"statement.cancel.supported";
+  public static final boolean DEFAULT_STATEMENT_CANCEL_SUPPORTED = true;
+
 }

http://git-wip-us.apache.org/repos/asf/lens/blob/9b402aee/lens-driver-jdbc/src/main/resources/jdbcdriver-default.xml
----------------------------------------------------------------------
diff --git a/lens-driver-jdbc/src/main/resources/jdbcdriver-default.xml 
b/lens-driver-jdbc/src/main/resources/jdbcdriver-default.xml
index 66645b9..89726c4 100644
--- a/lens-driver-jdbc/src/main/resources/jdbcdriver-default.xml
+++ b/lens-driver-jdbc/src/main/resources/jdbcdriver-default.xml
@@ -254,4 +254,11 @@
       is enabled by using 
org.apache.lens.server.api.query.constraint.MaxConcurrentDriverQueriesConstraintFactory
 as
       one of the factories in lens.driver.jdbc.query.constraint.factories 
property.</description>
   </property>
+
+  <property>
+    <name>lens.driver.jdbc.statement.cancel.supported</name>
+    <value>true</value>
+    <description>Flag to indicate Whether cancel on JDBC statement is 
supported. If not supported,
+      framework wont call cancel on JDBC statement.</description>
+  </property>
 </configuration>

http://git-wip-us.apache.org/repos/asf/lens/blob/9b402aee/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestJdbcDriver.java
----------------------------------------------------------------------
diff --git 
a/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestJdbcDriver.java
 
b/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestJdbcDriver.java
index 491aa69..e7636d2 100644
--- 
a/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestJdbcDriver.java
+++ 
b/lens-driver-jdbc/src/test/java/org/apache/lens/driver/jdbc/TestJdbcDriver.java
@@ -139,13 +139,17 @@ public class TestJdbcDriver {
   }
 
   synchronized void createTable(String table, Connection conn) throws 
Exception {
+    runTestSetupQuery(conn, "CREATE TABLE " + table + " (ID INT)");
+  }
+
+  void runTestSetupQuery(Connection conn, String query) throws Exception {
     Statement stmt = null;
     try {
       if (conn == null) {
         conn = driver.getConnection();
       }
       stmt = conn.createStatement();
-      stmt.execute("CREATE TABLE " + table + " (ID INT)");
+      stmt.execute(query);
 
       conn.commit();
     } finally {
@@ -163,13 +167,16 @@ public class TestJdbcDriver {
     insertData(table, null);
   }
 
+  void insertData(String table, Connection conn) throws Exception {
+    insertData(table, conn, 10);
+  }
   /**
    * Insert data.
    *
    * @param table the table
    * @throws Exception the exception
    */
-  void insertData(String table, Connection conn) throws Exception {
+  void insertData(String table, Connection conn, int numRows) throws Exception 
{
     PreparedStatement stmt = null;
     try {
       if (conn == null) {
@@ -177,7 +184,7 @@ public class TestJdbcDriver {
       }
       stmt = conn.prepareStatement("INSERT INTO " + table + " VALUES(?)");
 
-      for (int i = 0; i < 10; i++) {
+      for (int i = 0; i < numRows; i++) {
         stmt.setInt(1, i);
         stmt.executeUpdate();
       }
@@ -449,7 +456,7 @@ public class TestJdbcDriver {
 
 
   /**
-   * Data provider for test case {@link #testExecuteWithPreFetch()}
+   * Data provider for test case {@link #testExecuteWithPreFetch(int, boolean, 
int, boolean, long)} ()}
    * @return
    */
   @DataProvider
@@ -822,29 +829,58 @@ public class TestJdbcDriver {
     driver.execute(validCtx);
   }
 
+  public static int sleep(int t) {
+    try {
+      Thread.sleep(t * 1000);
+    } catch (InterruptedException ie) {
+      // ignore
+    }
+    return t;
+  }
+
+  @DataProvider(name = "waitBeforeCancel")
+  public Object[][] mediaTypeData() {
+    return new Object[][] {
+      {true},
+      {false},
+    };
+  }
+
+  boolean setupCancel = false;
+  private void setupCancelQuery() throws Exception {
+    if (!setupCancel) {
+      createTable("cancel_query_test");
+      insertData("cancel_query_test", null, 1);
+      final String function = "create function sleep(t int) returns int no sql 
language java PARAMETER STYLE JAVA"
+        + " EXTERNAL NAME 
'CLASSPATH:org.apache.lens.driver.jdbc.TestJdbcDriver.sleep'";
+      runTestSetupQuery(null, function);
+      setupCancel = true;
+    }
+  }
   /**
    * Test cancel query.
    *
    * @throws Exception the exception
    */
-  @Test
-  public void testCancelQuery() throws Exception {
-    createTable("cancel_query_test");
-    insertData("cancel_query_test");
-    final String query = "SELECT * FROM cancel_query_test";
+  @Test(dataProvider = "waitBeforeCancel")
+  public void testCancelQuery(boolean waitBeforeCancel) throws Exception {
+    setupCancelQuery();
+    // picked function as positive with udf mapping to sleep - sothat the 
signature of both are same.
+    // Here we need a UDF mapping because the function sleep is not available 
in Hive functions and semantic analysis
+    // would fail otherwise.
+    final String query = "SELECT positive(5) FROM cancel_query_test";
     QueryContext context = createQueryContext(query);
     System.out.println("@@@ test_cancel:" + context.getQueryHandle());
     executeAsync(context);
     QueryHandle handle = context.getQueryHandle();
+    // without wait query may not be launched.
+    if (waitBeforeCancel) {
+      Thread.sleep(100);
+    }
     boolean isCancelled = driver.cancelQuery(handle);
     driver.updateStatus(context);
-
-    if (isCancelled) {
-      assertEquals(context.getDriverStatus().getState(), 
DriverQueryState.CANCELED);
-    } else {
-      // Query completed before cancelQuery call
-      assertEquals(context.getDriverStatus().getState(), 
DriverQueryState.SUCCESSFUL);
-    }
+    assertTrue(isCancelled);
+    assertEquals(context.getDriverStatus().getState(), 
DriverQueryState.CANCELED);
 
     assertTrue(context.getDriverStatus().getDriverStartTime() > 0);
     assertTrue(context.getDriverStatus().getDriverFinishTime() > 0);

http://git-wip-us.apache.org/repos/asf/lens/blob/9b402aee/lens-driver-jdbc/src/test/resources/drivers/jdbc/jdbc1/jdbcdriver-site.xml
----------------------------------------------------------------------
diff --git 
a/lens-driver-jdbc/src/test/resources/drivers/jdbc/jdbc1/jdbcdriver-site.xml 
b/lens-driver-jdbc/src/test/resources/drivers/jdbc/jdbc1/jdbcdriver-site.xml
index 1202074..ac5e43d 100644
--- a/lens-driver-jdbc/src/test/resources/drivers/jdbc/jdbc1/jdbcdriver-site.xml
+++ b/lens-driver-jdbc/src/test/resources/drivers/jdbc/jdbc1/jdbcdriver-site.xml
@@ -64,7 +64,8 @@
 
   <property>
     <name>lens.driver.jdbc.regex.replacement.values</name>
-    <value>weekofyear=week, to_date=date, format_number=format, 
date_sub\((.*?)\,\s*([0-9]+\s*)\)=date_sub($1\, interval$2 day), 
date_add\((.*?)\,\s*([0-9]+\s*)\)=date_add($1\, interval $2 day)</value>
+    <value>weekofyear=week, to_date=date, format_number=format, 
date_sub\((.*?)\,\s*([0-9]+\s*)\)=date_sub($1\,
+        interval$2 day), date_add\((.*?)\,\s*([0-9]+\s*)\)=date_add($1\, 
interval $2 day),positive=sleep</value>
     <description>Rewriting the HQL to optimized sql queries</description>
   </property>
 </configuration>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/lens/blob/9b402aee/src/site/apt/admin/jdbcdriver-config.apt
----------------------------------------------------------------------
diff --git a/src/site/apt/admin/jdbcdriver-config.apt 
b/src/site/apt/admin/jdbcdriver-config.apt
index 96c98ad..c64d6ee 100644
--- a/src/site/apt/admin/jdbcdriver-config.apt
+++ b/src/site/apt/admin/jdbcdriver-config.apt
@@ -85,8 +85,10 @@ Jdbc driver configuration
 *--+--+---+--+
 |30|lens.driver.jdbc.regex.replacement.values|to_date=date, 
format_number=format, date_sub\((.*?)\,\s*([0-9]+\s*)\)=date_sub($1\, interval 
$2 day), date_add\((.*?)\,\s*([0-9]+\s*)\)=date_add($1\, interval $2 
day)|Rewriting the HQL to optimized sql queries|
 *--+--+---+--+
-|31|lens.driver.jdbc.validate.through.prepare|true|Flag to enable query 
syntactic and semantic validation using prepared statement.|
+|31|lens.driver.jdbc.statement.cancel.supported|true|Flag to indicate Whether 
cancel on JDBC statement is supported. If not supported, framework wont call 
cancel on JDBC statement.|
 *--+--+---+--+
-|32|lens.driver.jdbc.waiting.queries.selection.policy.factories|org.apache.lens.server.api.query.collect.DriverSpecificWaitingQueriesSelectionPolicyFactory|Factories
 used to instantiate driver specific waiting queries selection policies. Every 
factory should be an implementation of 
org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create 
an implementation of 
org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
+|32|lens.driver.jdbc.validate.through.prepare|true|Flag to enable query 
syntactic and semantic validation using prepared statement.|
+*--+--+---+--+
+|33|lens.driver.jdbc.waiting.queries.selection.policy.factories|org.apache.lens.server.api.query.collect.DriverSpecificWaitingQueriesSelectionPolicyFactory|Factories
 used to instantiate driver specific waiting queries selection policies. Every 
factory should be an implementation of 
org.apache.lens.server.api.common.ConfigBasedObjectCreationFactory and create 
an implementation of 
org.apache.lens.server.api.query.collect.WaitingQueriesSelectionPolicy.|
 *--+--+---+--+
 The configuration parameters and their default values

Reply via email to