You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by hu...@apache.org on 2022/11/16 02:13:52 UTC

[iotdb] branch master updated: [IOTDB-4900] Add check for URI when create Trigger/UDF (#8000)

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

hui pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 8b5d429ea7 [IOTDB-4900] Add check for URI when create Trigger/UDF (#8000)
8b5d429ea7 is described below

commit 8b5d429ea72d7a33bf102388a06795d21d11843d
Author: Liao Lanyu <14...@qq.com>
AuthorDate: Wed Nov 16 10:13:28 2022 +0800

    [IOTDB-4900] Add check for URI when create Trigger/UDF (#8000)
---
 .../db/it/trigger/IoTDBTriggerManagementIT.java    |  37 +++++++
 .../iotdb/db/it/udf/IoTDBUDFManagementIT.java      |  28 ++++++
 .../config/executor/ClusterConfigTaskExecutor.java | 111 ++++++++++++---------
 3 files changed, 127 insertions(+), 49 deletions(-)

diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/trigger/IoTDBTriggerManagementIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/trigger/IoTDBTriggerManagementIT.java
index a9de3b02d4..a96d54e8ae 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/trigger/IoTDBTriggerManagementIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/trigger/IoTDBTriggerManagementIT.java
@@ -424,6 +424,43 @@ public class IoTDBTriggerManagementIT {
     }
   }
 
+  @Test
+  public void testCreateTriggerWithInvalidURI() {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      try {
+        statement.execute(
+            String.format(
+                "create stateless trigger %s before insert on root.test.stateless.* as '%s' using URI '%s' with (\"name\"=\"%s\")",
+                STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "all",
+                TRIGGER_FILE_TIMES_COUNTER,
+                "",
+                STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "all"));
+        fail();
+      } catch (Exception e) {
+        assertTrue(e.getMessage().contains("URI"));
+      }
+
+      try {
+        statement.execute(
+            String.format(
+                "create stateless trigger %s before insert on root.test.stateless.* as '%s' using URI '%s' with (\"name\"=\"%s\")",
+                STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "all",
+                TRIGGER_FILE_TIMES_COUNTER,
+                "file:///data/trigger/upload-test.jar",
+                STATELESS_TRIGGER_BEFORE_INSERTION_PREFIX + "all"));
+        fail();
+      } catch (Exception e) {
+        assertTrue(e.getMessage().contains("URI"));
+      }
+
+      ResultSet resultSet = statement.executeQuery("show triggers");
+      assertFalse(resultSet.next());
+    } catch (Exception e) {
+      fail(e.getMessage());
+    }
+  }
+
   @Test
   public void testDropTriggersAfterCreationNormally() {
     try (Connection connection = EnvFactory.getEnv().getConnection();
diff --git a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFManagementIT.java b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFManagementIT.java
index ee52fb35ff..2984e84e5e 100644
--- a/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFManagementIT.java
+++ b/integration-test/src/test/java/org/apache/iotdb/db/it/udf/IoTDBUDFManagementIT.java
@@ -208,6 +208,34 @@ public class IoTDBUDFManagementIT {
     }
   }
 
+  @Test
+  public void testCreateFunctionWithInvalidURI() {
+    try (Connection connection = EnvFactory.getEnv().getConnection();
+        Statement statement = connection.createStatement()) {
+      try {
+        statement.execute(
+            String.format(
+                "create stateless trigger %s before insert on root.test.stateless.* as '%s' using URI '%s' with (\"name\"=\"%s\")",
+                "a", "org.apache.iotdb.test", "", "test"));
+        fail();
+      } catch (Exception e) {
+        assertTrue(e.getMessage().contains("URI"));
+      }
+
+      try {
+        statement.execute(
+            String.format(
+                "create stateless trigger %s before insert on root.test.stateless.* as '%s' using URI '%s' with (\"name\"=\"%s\")",
+                "a", "org.apache.iotdb.test", "file:///data/udf/upload-test.jar", "test"));
+        fail();
+      } catch (Exception e) {
+        assertTrue(e.getMessage().contains("URI"));
+      }
+    } catch (SQLException throwable) {
+      fail();
+    }
+  }
+
   @Test
   public void testDropFunction1() throws SQLException { // create + drop twice
     try (Connection connection = EnvFactory.getEnv().getConnection();
diff --git a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
index 43981a2848..0b8655a9ca 100644
--- a/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/mpp/plan/execution/config/executor/ClusterConfigTaskExecutor.java
@@ -297,9 +297,16 @@ public class ClusterConfigTaskExecutor implements IConfigTaskExecutor {
       String jarMd5;
       if (createFunctionStatement.isUsingURI()) {
         String uriString = createFunctionStatement.getUriString();
+        if (uriString == null || uriString.isEmpty()) {
+          future.setException(
+              new IoTDBException(
+                  "URI is empty, please specify the URI.",
+                  TSStatusCode.TRIGGER_DOWNLOAD_ERROR.getStatusCode()));
+          return future;
+        }
         jarFileName = new File(createFunctionStatement.getUriString()).getName();
-        if (!new URI(uriString).getScheme().equals("file")) {
-          try {
+        try {
+          if (!new URI(uriString).getScheme().equals("file")) {
             // download executable
             ExecutableResource resource =
                 UDFExecutableManager.getInstance().request(Collections.singletonList(uriString));
@@ -312,29 +319,28 @@ public class ClusterConfigTaskExecutor implements IConfigTaskExecutor {
             libRoot = jarFilePathUnderTempDir;
             jarFile = ExecutableManager.transferToBytebuffer(jarFilePathUnderTempDir);
             jarMd5 = DigestUtils.md5Hex(Files.newInputStream(Paths.get(jarFilePathUnderTempDir)));
-
-          } catch (IOException | URISyntaxException e) {
-            LOGGER.warn(
-                "Failed to download executable for UDF({}) using URI: {}, the cause is: {}",
-                createFunctionStatement.getUdfName(),
-                createFunctionStatement.getUriString(),
-                e);
-            future.setException(
-                new IoTDBException(
-                    "Failed to download executable for UDF '"
-                        + createFunctionStatement.getUdfName()
-                        + "'",
-                    TSStatusCode.TRIGGER_DOWNLOAD_ERROR.getStatusCode()));
-            return future;
+          } else {
+            // libRoot should be the path of the specified jar
+            libRoot = new File(new URI(uriString)).getAbsolutePath();
+            // If jarPath is a file path on datanode, we transfer it to ByteBuffer and send it to
+            // ConfigNode.
+            jarFile = ExecutableManager.transferToBytebuffer(libRoot);
+            // set md5 of the jar file
+            jarMd5 = DigestUtils.md5Hex(Files.newInputStream(Paths.get(libRoot)));
           }
-        } else {
-          // libRoot should be the path of the specified jar
-          libRoot = new File(new URI(uriString)).getAbsolutePath();
-          // If jarPath is a file path on datanode, we transfer it to ByteBuffer and send it to
-          // ConfigNode.
-          jarFile = ExecutableManager.transferToBytebuffer(libRoot);
-          // set md5 of the jar file
-          jarMd5 = DigestUtils.md5Hex(Files.newInputStream(Paths.get(libRoot)));
+        } catch (IOException | URISyntaxException e) {
+          LOGGER.warn(
+              "Failed to get executable for UDF({}) using URI: {}, the cause is: {}",
+              createFunctionStatement.getUdfName(),
+              createFunctionStatement.getUriString(),
+              e);
+          future.setException(
+              new IoTDBException(
+                  "Failed to get executable for UDF '"
+                      + createFunctionStatement.getUdfName()
+                      + "', please check the URI.",
+                  TSStatusCode.TRIGGER_DOWNLOAD_ERROR.getStatusCode()));
+          return future;
         }
         // modify req
         tCreateFunctionReq.setJarFile(jarFile);
@@ -378,7 +384,7 @@ public class ClusterConfigTaskExecutor implements IConfigTaskExecutor {
       } else {
         future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
       }
-    } catch (TException | IOException | URISyntaxException e) {
+    } catch (TException | IOException e) {
       future.setException(e);
     }
     return future;
@@ -448,9 +454,16 @@ public class ClusterConfigTaskExecutor implements IConfigTaskExecutor {
       String jarMd5;
       if (createTriggerStatement.isUsingURI()) {
         String uriString = createTriggerStatement.getUriString();
+        if (uriString == null || uriString.isEmpty()) {
+          future.setException(
+              new IoTDBException(
+                  "URI is empty, please specify the URI.",
+                  TSStatusCode.UDF_DOWNLOAD_ERROR.getStatusCode()));
+          return future;
+        }
         jarFileName = new File(createTriggerStatement.getUriString()).getName();
-        if (!new URI(uriString).getScheme().equals("file")) {
-          try {
+        try {
+          if (!new URI(uriString).getScheme().equals("file")) {
             // download executable
             ExecutableResource resource =
                 TriggerExecutableManager.getInstance()
@@ -465,28 +478,28 @@ public class ClusterConfigTaskExecutor implements IConfigTaskExecutor {
             jarFile = ExecutableManager.transferToBytebuffer(jarFilePathUnderTempDir);
             jarMd5 = DigestUtils.md5Hex(Files.newInputStream(Paths.get(jarFilePathUnderTempDir)));
 
-          } catch (IOException | URISyntaxException e) {
-            LOGGER.warn(
-                "Failed to download executable for Trigger({}) using URI: {}, the cause is: {}",
-                createTriggerStatement.getTriggerName(),
-                createTriggerStatement.getUriString(),
-                e);
-            future.setException(
-                new IoTDBException(
-                    "Failed to download executable for Trigger '"
-                        + createTriggerStatement.getUriString()
-                        + "'",
-                    TSStatusCode.TRIGGER_DOWNLOAD_ERROR.getStatusCode()));
-            return future;
+          } else {
+            // libRoot should be the path of the specified jar
+            libRoot = new File(new URI(uriString)).getAbsolutePath();
+            // If jarPath is a file path on datanode, we transfer it to ByteBuffer and send it to
+            // ConfigNode.
+            jarFile = ExecutableManager.transferToBytebuffer(libRoot);
+            // set md5 of the jar file
+            jarMd5 = DigestUtils.md5Hex(Files.newInputStream(Paths.get(libRoot)));
           }
-        } else {
-          // libRoot should be the path of the specified jar
-          libRoot = new File(new URI(uriString)).getAbsolutePath();
-          // If jarPath is a file path on datanode, we transfer it to ByteBuffer and send it to
-          // ConfigNode.
-          jarFile = ExecutableManager.transferToBytebuffer(libRoot);
-          // set md5 of the jar file
-          jarMd5 = DigestUtils.md5Hex(Files.newInputStream(Paths.get(libRoot)));
+        } catch (IOException | URISyntaxException e) {
+          LOGGER.warn(
+              "Failed to get executable for Trigger({}) using URI: {}, the cause is: {}",
+              createTriggerStatement.getTriggerName(),
+              createTriggerStatement.getUriString(),
+              e);
+          future.setException(
+              new IoTDBException(
+                  "Failed to get executable for Trigger '"
+                      + createTriggerStatement.getUriString()
+                      + "', please check the URI.",
+                  TSStatusCode.TRIGGER_DOWNLOAD_ERROR.getStatusCode()));
+          return future;
         }
         // modify req
         tCreateTriggerReq.setJarFile(jarFile);
@@ -537,7 +550,7 @@ public class ClusterConfigTaskExecutor implements IConfigTaskExecutor {
       } else {
         future.set(new ConfigTaskResult(TSStatusCode.SUCCESS_STATUS));
       }
-    } catch (TException | IOException | URISyntaxException e) {
+    } catch (TException | IOException e) {
       future.setException(e);
     }
     return future;