From b6961ce7a48267287c2562314e34fa7cb4ff3511 Mon Sep 17 00:00:00 2001 From: Sumit Kumar Date: Wed, 10 Mar 2021 11:11:14 +0530 Subject: [PATCH] Add timeout failure for mongo plugin test datasource (#3431) - Mongo plugin client driver does not return with exception upon first failure - instead it keeps retrying. Hence, adding timeout error to report failure before the client thread cancels due to delay in response. - It seems that the mongdb connection string cannot be directly used for ping test, hence skipping it. --- .../cypress/manual_TestSuite/Modal_Spec.js | 2 +- .../manual_TestSuite/new_Table_Spec.js | 2 +- .../pluginExceptions/AppsmithPluginError.java | 1 + .../com/external/plugins/MongoPlugin.java | 14 +++++++++++ .../com/external/plugins/MongoPluginTest.java | 24 +++++++++++++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/client/cypress/manual_TestSuite/Modal_Spec.js b/app/client/cypress/manual_TestSuite/Modal_Spec.js index 35fe46400b..1c183dec0b 100644 --- a/app/client/cypress/manual_TestSuite/Modal_Spec.js +++ b/app/client/cypress/manual_TestSuite/Modal_Spec.js @@ -47,4 +47,4 @@ it("Convert Modal to ", function() ) } -) \ No newline at end of file +) diff --git a/app/client/cypress/manual_TestSuite/new_Table_Spec.js b/app/client/cypress/manual_TestSuite/new_Table_Spec.js index e3aa7d9e9f..d7742fe184 100644 --- a/app/client/cypress/manual_TestSuite/new_Table_Spec.js +++ b/app/client/cypress/manual_TestSuite/new_Table_Spec.js @@ -50,4 +50,4 @@ describe("Table functionality ", function() { ) } -) \ No newline at end of file +) diff --git a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/exceptions/pluginExceptions/AppsmithPluginError.java b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/exceptions/pluginExceptions/AppsmithPluginError.java index 23fbd3f7c0..9e6b5ae991 100644 --- a/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/exceptions/pluginExceptions/AppsmithPluginError.java +++ b/app/server/appsmith-interfaces/src/main/java/com/appsmith/external/exceptions/pluginExceptions/AppsmithPluginError.java @@ -21,6 +21,7 @@ public enum AppsmithPluginError { AppsmithErrorAction.DEFAULT), PLUGIN_DATASOURCE_TEST_GENERIC_ERROR(500, 5007, "Plugin failed to test with the given configuration. Please reach out to Appsmith customer support to report this", AppsmithErrorAction.LOG_EXTERNALLY), + PLUGIN_DATASOURCE_TIMEOUT_ERROR(504, 5008, "{0}", AppsmithErrorAction.DEFAULT), ; private final Integer httpErrorCode; diff --git a/app/server/appsmith-plugins/mongoPlugin/src/main/java/com/external/plugins/MongoPlugin.java b/app/server/appsmith-plugins/mongoPlugin/src/main/java/com/external/plugins/MongoPlugin.java index 8cb64bb2a4..900880a81c 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/main/java/com/external/plugins/MongoPlugin.java +++ b/app/server/appsmith-plugins/mongoPlugin/src/main/java/com/external/plugins/MongoPlugin.java @@ -16,6 +16,7 @@ import com.appsmith.external.models.SSLDetails; import com.appsmith.external.plugins.BasePlugin; import com.appsmith.external.plugins.PluginExecutor; import com.mongodb.MongoCommandException; +import com.mongodb.MongoTimeoutException; import com.mongodb.reactivestreams.client.MongoClient; import com.mongodb.reactivestreams.client.MongoClients; import com.mongodb.reactivestreams.client.MongoDatabase; @@ -39,6 +40,7 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.time.Instant; import java.time.format.DateTimeFormatter; import java.util.ArrayList; @@ -50,6 +52,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; public class MongoPlugin extends BasePlugin { @@ -70,6 +73,8 @@ public class MongoPlugin extends BasePlugin { private static final String VALUE_STR = "value"; + private static final int TEST_DATASOURCE_TIMEOUT_SECONDS = 15; + public MongoPlugin(PluginWrapper wrapper) { super(wrapper); } @@ -382,6 +387,15 @@ public class MongoPlugin extends BasePlugin { } }) .then(Mono.just(new DatasourceTestResult())) + .timeout(Duration.ofSeconds(TEST_DATASOURCE_TIMEOUT_SECONDS)) + .onErrorMap( + TimeoutException.class, + error -> new AppsmithPluginException( + AppsmithPluginError.PLUGIN_DATASOURCE_TIMEOUT_ERROR, + "Connection timed out. Please check if the datasource configuration fields have " + + "been filled correctly." + ) + ) .onErrorResume(error -> { /** * 1. Return OK response on "Unauthorized" exception. diff --git a/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginTest.java b/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginTest.java index e7a8e1ae0a..ebcfb4986f 100644 --- a/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginTest.java +++ b/app/server/appsmith-plugins/mongoPlugin/src/test/java/com/external/plugins/MongoPluginTest.java @@ -5,6 +5,7 @@ import com.appsmith.external.models.ActionExecutionResult; import com.appsmith.external.models.Connection; import com.appsmith.external.models.DatasourceConfiguration; import com.appsmith.external.models.DatasourceStructure; +import com.appsmith.external.models.DatasourceTestResult; import com.appsmith.external.models.Endpoint; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -420,4 +421,27 @@ public class MongoPluginTest { }) .verifyComplete(); } + + @Test + public void testTestDatasourceTimeoutError() { + String badHost = "mongo-bad-url.mongodb.net"; + DatasourceConfiguration dsConfig = createDatasourceConfiguration(); + dsConfig.getEndpoints().get(0).setHost(badHost); + + Mono datasourceTestResult = pluginExecutor.testDatasource(dsConfig); + + StepVerifier.create(datasourceTestResult) + .assertNext(result -> { + assertFalse(result.isSuccess()); + assertTrue(result.getInvalids().size() == 1); + assertTrue(result + .getInvalids() + .stream() + .anyMatch(error -> error.contains( + "Connection timed out. Please check if the datasource configuration fields have " + + "been filled correctly." + ))); + }) + .verifyComplete(); + } }