diff --git a/app/server/appsmith-plugins/redisPlugin/pom.xml b/app/server/appsmith-plugins/redisPlugin/pom.xml index 2be6893d04..f41de124e4 100644 --- a/app/server/appsmith-plugins/redisPlugin/pom.xml +++ b/app/server/appsmith-plugins/redisPlugin/pom.xml @@ -49,13 +49,20 @@ redis.clients jedis 3.3.0 + + + org.slf4j + slf4j-api + + + junit junit - 4.11 + 4.13.1 test @@ -74,7 +81,7 @@ org.testcontainers testcontainers - 1.14.1 + 1.15.0-rc2 test @@ -109,6 +116,23 @@ + + maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + runtime + ${project.build.directory}/lib + + + + + diff --git a/app/server/appsmith-plugins/redisPlugin/src/main/java/com/external/plugins/RedisPlugin.java b/app/server/appsmith-plugins/redisPlugin/src/main/java/com/external/plugins/RedisPlugin.java index 96695c737f..fadee2dc18 100644 --- a/app/server/appsmith-plugins/redisPlugin/src/main/java/com/external/plugins/RedisPlugin.java +++ b/app/server/appsmith-plugins/redisPlugin/src/main/java/com/external/plugins/RedisPlugin.java @@ -1,6 +1,11 @@ package com.external.plugins; -import com.appsmith.external.models.*; +import com.appsmith.external.models.ActionConfiguration; +import com.appsmith.external.models.ActionExecutionResult; +import com.appsmith.external.models.AuthenticationDTO; +import com.appsmith.external.models.DatasourceConfiguration; +import com.appsmith.external.models.DatasourceTestResult; +import com.appsmith.external.models.Endpoint; import com.appsmith.external.pluginExceptions.AppsmithPluginError; import com.appsmith.external.pluginExceptions.AppsmithPluginException; import com.appsmith.external.plugins.BasePlugin; @@ -19,7 +24,10 @@ import redis.clients.jedis.util.SafeEncoder; import java.util.Arrays; import java.util.HashSet; +import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; public class RedisPlugin extends BasePlugin { private static final Integer DEFAULT_PORT = 6379; @@ -61,19 +69,25 @@ public class RedisPlugin extends BasePlugin { } ActionExecutionResult actionExecutionResult = new ActionExecutionResult(); - actionExecutionResult.setBody(processCommandOutput(commandOutput)); + actionExecutionResult.setBody(objectMapper.valueToTree(processCommandOutput(commandOutput))); + actionExecutionResult.setIsExecutionSuccess(true); return Mono.just(actionExecutionResult); } // This will be updated as we encounter different outputs. - private String processCommandOutput(Object commandOutput) { + private List> processCommandOutput(Object commandOutput) { if (commandOutput == null) { - return "null"; + return List.of(Map.of("result", "null")); } else if (commandOutput instanceof byte[]) { - return SafeEncoder.encode((byte[]) commandOutput); + return List.of(Map.of("result", SafeEncoder.encode((byte[]) commandOutput))); + } else if (commandOutput instanceof List) { + List commandList = (List) commandOutput; + return commandList.stream() + .map(obj -> Map.of("result", SafeEncoder.encode(obj))) + .collect(Collectors.toList()); } else { - return String.valueOf(commandOutput); + return List.of(Map.of("result", String.valueOf(commandOutput))); } } @@ -151,13 +165,13 @@ public class RedisPlugin extends BasePlugin { @Override public Mono testDatasource(DatasourceConfiguration datasourceConfiguration) { - return datasourceCreate(datasourceConfiguration). - map(jedis -> { + return datasourceCreate(datasourceConfiguration) + .map(jedis -> { verifyPing(jedis).block(); datasourceDestroy(jedis); return new DatasourceTestResult(); - }). - onErrorResume(error -> Mono.just(new DatasourceTestResult(error.getMessage()))); + }) + .onErrorResume(error -> Mono.just(new DatasourceTestResult(error.getMessage()))); } } diff --git a/app/server/appsmith-plugins/redisPlugin/src/main/resources/editor.json b/app/server/appsmith-plugins/redisPlugin/src/main/resources/editor.json new file mode 100644 index 0000000000..7896a10ac6 --- /dev/null +++ b/app/server/appsmith-plugins/redisPlugin/src/main/resources/editor.json @@ -0,0 +1,15 @@ +{ + "editor": [ + { + "sectionName": "", + "id": 1, + "children": [ + { + "label": "", + "configProperty": "actionConfiguration.body", + "controlType": "QUERY_DYNAMIC_TEXT" + } + ] + } + ] +} \ No newline at end of file diff --git a/app/server/appsmith-plugins/redisPlugin/src/main/resources/form.json b/app/server/appsmith-plugins/redisPlugin/src/main/resources/form.json new file mode 100644 index 0000000000..1ffb55a76e --- /dev/null +++ b/app/server/appsmith-plugins/redisPlugin/src/main/resources/form.json @@ -0,0 +1,52 @@ +{ + "form": [ + { + "sectionName": "Connection", + "id": 1, + "children": [ + { + "sectionName": null, + "children": [ + { + "label": "Host Address", + "configProperty": "datasourceConfiguration.endpoints[*].host", + "controlType": "KEYVALUE_ARRAY", + "validationMessage": "Please enter a valid host", + "validationRegex": "^((?![/:]).)*$" + }, + { + "label": "Port", + "configProperty": "datasourceConfiguration.endpoints[*].port", + "dataType": "NUMBER", + "controlType": "KEYVALUE_ARRAY" + } + ] + } + ] + }, + { + "sectionName": "Authentication", + "id": 2, + "children": [ + { + "sectionName": null, + "children": [ + { + "label": "Username", + "configProperty": "datasourceConfiguration.authentication.username", + "controlType": "INPUT_TEXT", + "placeholderText": "Username" + }, + { + "label": "Password", + "configProperty": "datasourceConfiguration.authentication.password", + "dataType": "PASSWORD", + "controlType": "INPUT_TEXT", + "placeholderText": "Password" + } + ] + } + ] + } + ] +} diff --git a/app/server/appsmith-plugins/redisPlugin/src/test/java/com/external/plugins/RedisPluginTest.java b/app/server/appsmith-plugins/redisPlugin/src/test/java/com/external/plugins/RedisPluginTest.java index 8ec264ca6c..9728700a9e 100644 --- a/app/server/appsmith-plugins/redisPlugin/src/test/java/com/external/plugins/RedisPluginTest.java +++ b/app/server/appsmith-plugins/redisPlugin/src/test/java/com/external/plugins/RedisPluginTest.java @@ -1,7 +1,14 @@ package com.external.plugins; -import com.appsmith.external.models.*; +import com.appsmith.external.models.ActionConfiguration; +import com.appsmith.external.models.ActionExecutionResult; +import com.appsmith.external.models.AuthenticationDTO; +import com.appsmith.external.models.DatasourceConfiguration; +import com.appsmith.external.models.DatasourceTestResult; +import com.appsmith.external.models.Endpoint; import com.appsmith.external.pluginExceptions.AppsmithPluginException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import lombok.extern.slf4j.Slf4j; import org.junit.Assert; import org.junit.BeforeClass; @@ -166,7 +173,8 @@ public class RedisPluginTest { .assertNext(actionExecutionResult -> { Assert.assertNotNull(actionExecutionResult); Assert.assertNotNull(actionExecutionResult.getBody()); - Assert.assertEquals(actionExecutionResult.getBody(), "PONG"); + final JsonNode node = ((ArrayNode) actionExecutionResult.getBody()).get(0); + Assert.assertEquals(node.get("result").asText(), "PONG"); }).verifyComplete(); } @@ -184,7 +192,8 @@ public class RedisPluginTest { .assertNext(actionExecutionResult -> { Assert.assertNotNull(actionExecutionResult); Assert.assertNotNull(actionExecutionResult.getBody()); - Assert.assertEquals(actionExecutionResult.getBody(), "null"); + final JsonNode node = ((ArrayNode) actionExecutionResult.getBody()).get(0); + Assert.assertEquals(node.get("result").asText(), "null"); }).verifyComplete(); // Setting a key @@ -196,7 +205,8 @@ public class RedisPluginTest { .assertNext(actionExecutionResult -> { Assert.assertNotNull(actionExecutionResult); Assert.assertNotNull(actionExecutionResult.getBody()); - Assert.assertEquals(actionExecutionResult.getBody(), "OK"); + final JsonNode node = ((ArrayNode) actionExecutionResult.getBody()).get(0); + Assert.assertEquals(node.get("result").asText(), "OK"); }).verifyComplete(); // Getting the key @@ -206,7 +216,8 @@ public class RedisPluginTest { .assertNext(actionExecutionResult -> { Assert.assertNotNull(actionExecutionResult); Assert.assertNotNull(actionExecutionResult.getBody()); - Assert.assertEquals(actionExecutionResult.getBody(), "value"); + final JsonNode node = ((ArrayNode) actionExecutionResult.getBody()).get(0); + Assert.assertEquals(node.get("result").asText(), "value"); }).verifyComplete(); } } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog.java index 79ba6acda7..2c5a106bde 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/migrations/DatabaseChangelog.java @@ -974,6 +974,26 @@ public class DatabaseChangelog { ); } + @ChangeSet(order = "030", id = "add-redis-plugin", author = "") + public void addRedisPlugin(MongoTemplate mongoTemplate) { + Plugin plugin1 = new Plugin(); + plugin1.setName("Redis"); + plugin1.setType(PluginType.DB); + plugin1.setPackageName("redis-plugin"); + plugin1.setUiComponent("DbEditorForm"); + plugin1.setResponseType(Plugin.ResponseType.TABLE); + plugin1.setIconLocation("https://s3.us-east-2.amazonaws.com/assets.appsmith.com/redis.jpg"); + plugin1.setDocumentationLink("https://docs.appsmith.com/core-concepts/connecting-to-databases/querying-redis"); + plugin1.setDefaultInstall(true); + try { + mongoTemplate.insert(plugin1); + } catch (DuplicateKeyException e) { + log.warn(plugin1.getPackageName() + " already present in database."); + } + + installPluginToAllOrganizations(mongoTemplate, plugin1.getId()); + } + private void installPluginToAllOrganizations(MongoTemplate mongoTemplate, String pluginId) { for (Organization organization : mongoTemplate.findAll(Organization.class)) { if (CollectionUtils.isEmpty(organization.getPlugins())) {