plugin: Support format record

This commit is contained in:
qianmoQ 2022-09-21 13:37:35 +08:00
parent 460c69ecfc
commit e8d5e95d1b
19 changed files with 185 additions and 22 deletions

View File

@ -38,9 +38,5 @@
<groupId>com.google.code.findbugs</groupId>
<artifactId>findbugs</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>findbugs</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,10 @@
package io.edurt.datacap.plugin.jdbc.mysql;
import io.edurt.datacap.spi.adapter.Adapter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class MySQLAdapter
extends Adapter
{
}

View File

@ -84,6 +84,11 @@ public class MySQLConnection
return this.response;
}
public Configure getConfigure()
{
return this.configure;
}
public void destroy()
{
if (ObjectUtils.isNotEmpty(this.connection)) {

View File

@ -2,9 +2,12 @@ package io.edurt.datacap.plugin.jdbc.mysql;
import io.edurt.datacap.spi.Plugin;
import io.edurt.datacap.spi.PluginType;
import io.edurt.datacap.spi.adapter.Adapter;
import io.edurt.datacap.spi.model.Configure;
import io.edurt.datacap.spi.model.Response;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class MySQLPlugin
implements Plugin
{
@ -34,8 +37,12 @@ public class MySQLPlugin
@Override
public Response execute(String content)
{
MySQLProcessor processor = new MySQLProcessor(this.connection);
return processor.handlerExecute(content);
log.info("Execute plugin logic started");
response = this.connection.getResponse();
Adapter processor = new MySQLAdapter();
processor.handlerJDBCExecute(this.connection.getConfigure().getFormat(), content, this.connection.getConnection(), response);
log.info("Execute plugin logic end");
return response;
}
@Override

11
pom.xml
View File

@ -24,6 +24,7 @@
<commons-lang3.version>3.12.0</commons-lang3.version>
<slf4j.version>1.7.36</slf4j.version>
<findbugs.version>3.0.1</findbugs.version>
<jackson.version>2.13.3</jackson.version>
<plugin.maven.checkstyle.version>3.0.0</plugin.maven.checkstyle.version>
<plugin.maven.findbugs.version>3.0.5</plugin.maven.findbugs.version>
<plugin.maven.compiler.version>3.3</plugin.maven.compiler.version>
@ -87,6 +88,16 @@
<artifactId>findbugs</artifactId>
<version>${findbugs.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>

View File

@ -1,5 +1,6 @@
package io.edurt.datacap.server.entity;
import io.edurt.datacap.spi.FormatType;
import lombok.Data;
import lombok.ToString;
@ -12,4 +13,5 @@ public class ExecuteEntity
private String name;
private String content;
private Map<String, Object> env;
private FormatType format = FormatType.NONE;
}

View File

@ -53,6 +53,7 @@ public class ExecuteServiceImpl
_configure.setUsername(Optional.ofNullable(entity.getUsername()));
_configure.setPassword(Optional.ofNullable(entity.getPassword()));
_configure.setEnv(Optional.ofNullable(configure.getEnv()));
_configure.setFormat(configure.getFormat());
plugin.connect(_configure);
io.edurt.datacap.spi.model.Response response = plugin.execute(configure.getContent());
plugin.destroy();

View File

@ -26,7 +26,7 @@ public class BaseParamTest
{
ExecuteEntity configure = new ExecuteEntity();
configure.setName("MySQL");
configure.setContent("SHOW DATABASES");
configure.setContent("SELECT * FROM information_schema.TABLES LIMIT 100");
return configure;
}
}

View File

@ -2,6 +2,8 @@ package io.edurt.datacap.server.controller;
import io.edurt.datacap.server.BaseParamTest;
import io.edurt.datacap.server.common.JSON;
import io.edurt.datacap.server.entity.ExecuteEntity;
import io.edurt.datacap.spi.FormatType;
import lombok.extern.slf4j.Slf4j;
import org.junit.Before;
import org.junit.Test;
@ -54,4 +56,24 @@ public class ExecuteControllerTest
.andReturn();
log.info(mvcResult.getResponse().getContentAsString());
}
@Test
@SqlGroup(value = {
@Sql(value = "classpath:schema/source.sql"),
@Sql(value = "classpath:data/source.sql")
})
public void executeFormatJson()
throws Exception
{
ExecuteEntity entity = BaseParamTest.builderExecute();
entity.setFormat(FormatType.JSON);
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/api/v1/execute")
.contentType(MediaType.APPLICATION_JSON)
.content(JSON.objectmapper.writeValueAsString(entity)))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.code").exists())
.andDo(MockMvcResultHandlers.print())
.andReturn();
log.info(mvcResult.getResponse().getContentAsString());
}
}

View File

@ -27,7 +27,7 @@ public class ExecuteServiceTest
{
ExecuteEntity configure = new ExecuteEntity();
configure.setName("MySQL");
configure.setContent("SHOW TABLES");
configure.setContent("SHOW DATABASES");
Assert.assertTrue(ObjectUtils.isNotEmpty(executeService.execute(configure)));
}
}

View File

@ -26,5 +26,17 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>findbugs</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,7 @@
package io.edurt.datacap.spi;
public enum FormatType
{
NONE,
JSON
}

View File

@ -1,9 +1,12 @@
package io.edurt.datacap.plugin.jdbc.mysql;
package io.edurt.datacap.spi.adapter;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.edurt.datacap.spi.FormatType;
import io.edurt.datacap.spi.model.Response;
import io.edurt.datacap.spi.record.RecordFactory;
import lombok.extern.slf4j.Slf4j;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
@ -14,24 +17,20 @@ import java.util.List;
@Slf4j
@SuppressFBWarnings(value = {"RCN_REDUNDANT_NULLCHECK_WOULD_HAVE_BEEN_A_NPE"},
justification = "I prefer to suppress these FindBugs warnings")
public class MySQLProcessor
public abstract class Adapter
{
private final MySQLConnection connection;
public MySQLProcessor(MySQLConnection connection)
private Object handlerFormatAdapterRecord(FormatType format, List<String> headers, List<Object> columns)
{
this.connection = connection;
return RecordFactory.createRecord(format, headers, columns).convert();
}
public Response handlerExecute(String content)
public Response handlerJDBCExecute(FormatType format, String content, Connection connection, Response response)
{
Response response = this.connection.getResponse();
if (response.getIsConnected()) {
try (Statement statement = this.connection.getConnection().createStatement();
ResultSet resultSet = statement.executeQuery(content)) {
try (Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(content)) {
List<String> headers = new ArrayList<>();
List<String> types = new ArrayList<>();
List<List<Object>> columns = new ArrayList<>();
List<Object> columns = new ArrayList<>();
boolean isPresent = true;
while (resultSet.next()) {
ResultSetMetaData metaData = resultSet.getMetaData();
@ -45,7 +44,7 @@ public class MySQLProcessor
_columns.add(resultSet.getString(i));
}
isPresent = false;
columns.add(_columns);
columns.add(handlerFormatAdapterRecord(format, headers, _columns));
}
response.setHeaders(headers);
response.setTypes(types);
@ -53,7 +52,7 @@ public class MySQLProcessor
response.setIsSuccessful(Boolean.TRUE);
}
catch (SQLException ex) {
log.error("Execute content failed content {} exception {}", content, ex);
log.error("Execute content failed content {} exception ", content, ex);
response.setIsSuccessful(Boolean.FALSE);
response.setMessage(ex.getMessage());
}

View File

@ -1,5 +1,6 @@
package io.edurt.datacap.spi.model;
import io.edurt.datacap.spi.FormatType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@ -20,4 +21,5 @@ public class Configure
private Optional<String> password = Optional.empty();
private Optional<String> database = Optional.empty();
private Optional<Map<String, Object>> env = Optional.empty();
private FormatType format = FormatType.NONE;
}

View File

@ -15,7 +15,7 @@ public class Response
{
private List<String> headers;
private List<String> types;
private List<List<Object>> columns;
private List<Object> columns;
private Boolean isConnected = Boolean.FALSE;
private Boolean isSuccessful = Boolean.FALSE;
private String message;

View File

@ -0,0 +1,26 @@
package io.edurt.datacap.spi.record;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.List;
public class JsonRecord
extends Record
{
protected JsonRecord(List<String> headers, List<Object> columns)
{
super(headers, columns);
}
@Override
public Object convert()
{
ObjectMapper mapper = new ObjectMapper();
ObjectNode node = mapper.createObjectNode();
for (int i = 0; i < headers.size(); i++) {
node.put(headers.get(i), String.valueOf(columns.get(i)));
}
return node;
}
}

View File

@ -0,0 +1,23 @@
package io.edurt.datacap.spi.record;
import java.util.ArrayList;
import java.util.List;
public class NoneRecord
extends Record
{
protected NoneRecord(List<String> headers, List<Object> columns)
{
super(headers, columns);
}
@Override
public Object convert()
{
List<Object> values = new ArrayList<>();
for (int i = 0; i < headers.size(); i++) {
values.add(columns.get(i));
}
return values;
}
}

View File

@ -0,0 +1,17 @@
package io.edurt.datacap.spi.record;
import java.util.List;
public abstract class Record
{
protected final List<String> headers;
protected final List<Object> columns;
protected Record(List<String> headers, List<Object> columns)
{
this.headers = headers;
this.columns = columns;
}
public abstract Object convert();
}

View File

@ -0,0 +1,23 @@
package io.edurt.datacap.spi.record;
import io.edurt.datacap.spi.FormatType;
import java.util.List;
public class RecordFactory
{
private RecordFactory()
{}
public static Record createRecord(FormatType format, List<String> headers, List<Object> columns)
{
Record instance;
if (format.equals(FormatType.JSON)) {
instance = new JsonRecord(headers, columns);
}
else {
instance = new NoneRecord(headers, columns);
}
return instance;
}
}