From b98caa58c9f51021584e2158aaee8fd02679d53e Mon Sep 17 00:00:00 2001
From: qianmoQ
Date: Tue, 25 Apr 2023 11:52:09 +0800
Subject: [PATCH] [Plugin] [JDBC] Support hologres
---
README.md | 3 +
core/datacap-server/pom.xml | 5 +
.../main/etc/conf/plugins/jdbc/hologres.yaml | 31 +++++++
.../java/io/edurt/datacap/spi/Plugin.java | 7 +-
.../public/static/images/plugin/Hologres.png | Bin 0 -> 6978 bytes
docs/docs/assets/plugin/hologres.png | Bin 0 -> 6978 bytes
.../reference/connectors/jdbc/hologres.md | 57 ++++++++++++
.../reference/connectors/jdbc/hologres.zh.md | 57 ++++++++++++
docs/mkdocs.yml | 1 +
plugin/datacap-jdbc-hologres/pom.xml | 87 ++++++++++++++++++
.../datacap/jdbc/hologres/HologresPlugin.kt | 60 ++++++++++++
.../jdbc/hologres/HologresPluginModule.kt | 26 ++++++
.../io.edurt.datacap.spi.PluginModule | 1 +
.../jdbc/hologres/HologresContainer.kt | 18 ++++
.../jdbc/hologres/HologresPluginModuleTest.kt | 29 ++++++
.../jdbc/hologres/HologresPluginTest.kt | 75 +++++++++++++++
pom.xml | 1 +
17 files changed, 456 insertions(+), 2 deletions(-)
create mode 100644 core/datacap-server/src/main/etc/conf/plugins/jdbc/hologres.yaml
create mode 100644 core/datacap-web/console-fe/public/static/images/plugin/Hologres.png
create mode 100644 docs/docs/assets/plugin/hologres.png
create mode 100644 docs/docs/reference/connectors/jdbc/hologres.md
create mode 100644 docs/docs/reference/connectors/jdbc/hologres.zh.md
create mode 100644 plugin/datacap-jdbc-hologres/pom.xml
create mode 100644 plugin/datacap-jdbc-hologres/src/main/kotlin/io/edurt/datacap/jdbc/hologres/HologresPlugin.kt
create mode 100644 plugin/datacap-jdbc-hologres/src/main/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginModule.kt
create mode 100644 plugin/datacap-jdbc-hologres/src/main/resources/META-INF/services/io.edurt.datacap.spi.PluginModule
create mode 100644 plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresContainer.kt
create mode 100644 plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginModuleTest.kt
create mode 100644 plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginTest.kt
diff --git a/README.md b/README.md
index 2d63bb0c..8982e106 100644
--- a/README.md
+++ b/README.md
@@ -172,6 +172,9 @@ Here are some of the major database solutions that are supported:
+
+
+
diff --git a/core/datacap-server/pom.xml b/core/datacap-server/pom.xml
index 1ae3af04..5b9e8087 100644
--- a/core/datacap-server/pom.xml
+++ b/core/datacap-server/pom.xml
@@ -340,6 +340,11 @@
datacap-jdbc-starrocks
${project.version}
+
+ io.edurt.datacap
+ datacap-jdbc-hologres
+ ${project.version}
+
io.edurt.datacap
diff --git a/core/datacap-server/src/main/etc/conf/plugins/jdbc/hologres.yaml b/core/datacap-server/src/main/etc/conf/plugins/jdbc/hologres.yaml
new file mode 100644
index 00000000..ca58f0f0
--- /dev/null
+++ b/core/datacap-server/src/main/etc/conf/plugins/jdbc/hologres.yaml
@@ -0,0 +1,31 @@
+name: Hologres
+supportTime: '2023-04-25'
+configures:
+ - field: name
+ type: String
+ required: true
+ message: name is a required field, please be sure to enter
+ - field: host
+ type: String
+ required: true
+ value: hologres-cn-regison.aliyuncs.com
+ message: host is a required field, please be sure to enter
+ - field: port
+ type: Number
+ required: true
+ min: 1
+ max: 65535
+ value: 80
+ message: port is a required field, please be sure to enter
+ - field: username
+ type: String
+ group: authorization
+ - field: password
+ type: String
+ group: authorization
+ - field: database
+ type: String
+ required: true
+ value: default
+ message: database is a required field, please be sure to enter
+ group: advanced
diff --git a/core/datacap-spi/src/main/java/io/edurt/datacap/spi/Plugin.java b/core/datacap-spi/src/main/java/io/edurt/datacap/spi/Plugin.java
index f092b4af..4d5aefc7 100644
--- a/core/datacap-spi/src/main/java/io/edurt/datacap/spi/Plugin.java
+++ b/core/datacap-spi/src/main/java/io/edurt/datacap/spi/Plugin.java
@@ -10,12 +10,15 @@ public interface Plugin
return "SELECT version() AS version";
}
+ default PluginType type()
+ {
+ return PluginType.JDBC;
+ }
+
String name();
String description();
- PluginType type();
-
void connect(Configure configure);
Response execute(String content);
diff --git a/core/datacap-web/console-fe/public/static/images/plugin/Hologres.png b/core/datacap-web/console-fe/public/static/images/plugin/Hologres.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b28ac9d8e9523790617b3c19ddc7398c5c28fb3
GIT binary patch
literal 6978
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
literal 0
HcmV?d00001
diff --git a/docs/docs/assets/plugin/hologres.png b/docs/docs/assets/plugin/hologres.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b28ac9d8e9523790617b3c19ddc7398c5c28fb3
GIT binary patch
literal 6978
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
literal 0
HcmV?d00001
diff --git a/docs/docs/reference/connectors/jdbc/hologres.md b/docs/docs/reference/connectors/jdbc/hologres.md
new file mode 100644
index 00000000..2b7facb0
--- /dev/null
+++ b/docs/docs/reference/connectors/jdbc/hologres.md
@@ -0,0 +1,57 @@
+---
+title: Hologres
+status: new
+---
+
+
+
+#### What is Hologres ?
+
+Hologres is an all-in-one real-time data warehouse engine that is compatible with PostgreSQL. It supports online analytical processing (OLAP) and ad hoc analysis of PB-scale data. Hologres supports online data serving at high concurrency and low latency. It is deeply integrated with MaxCompute, Flink and DataWorks, provides a full-stack data warehouse solution that integrates online and offline processing.
+
+#### Environment
+
+!!! note
+
+ If you need to use this data source, you need to upgrade the DataCap service to >= `1.9.x`
+
+Support Time: `2023-04-25`
+
+#### Configure
+
+---
+
+!!! note
+
+ If your Hologres service version requires other special configurations, please refer to modifying the configuration file and restarting the DataCap service.
+
+=== "Configure"
+
+ | Field | Required | Default Value |
+ |:------:|:---------------------------------:|:-------------:|
+ | `Name` | :material-check-circle: { .red } | - |
+ | `Host` | :material-check-circle: { .red } | `hologres-cn-regison.aliyuncs.com` |
+ | `Port` | :material-check-circle: { .red } | `80` |
+
+=== "Authorization"
+
+ | Field | Required | Default Value |
+ |:----------:|:-----------------------:|:-------------:|
+ | `Username` | :material-close-circle: | - |
+ | `Password` | :material-close-circle: | - |
+
+=== "Advanced"
+
+ | Field | Required | Default Value |
+ |:----------:|:-----------------------:|:-------------:|
+ | `Database` | :material-close-circle: | - |
+
+#### Version (Validation)
+
+---
+
+!!! warning
+
+ The online service has not been tested yet, if you have detailed test results, please submit [issues](https://github.com/EdurtIO/datacap/issues/new/choose) to us
+
+- [x] all
diff --git a/docs/docs/reference/connectors/jdbc/hologres.zh.md b/docs/docs/reference/connectors/jdbc/hologres.zh.md
new file mode 100644
index 00000000..cd604d60
--- /dev/null
+++ b/docs/docs/reference/connectors/jdbc/hologres.zh.md
@@ -0,0 +1,57 @@
+---
+title: Hologres
+status: new
+---
+
+
+
+#### 什么是 Hologres ?
+
+Hologres是兼容PostgreSQL的一站式实时数据仓库引擎,支持PB级数据多维分析(OLAP)与即席分析(Ad Hoc),支持高并发低延迟的在线数据服务(Serving)。与MaxCompute、Flink、DataWorks深度融合,提供离在线一体化全栈数仓解决方案。
+
+#### 环境
+
+!!! note
+
+ 如果你需要使用这个数据源, 您需要将 DataCap 服务升级到 >= `1.9.x`
+
+支持时间: `2023-04-25`
+
+#### 配置
+
+---
+
+!!! note
+
+ 如果您的 Hologres 服务版本需要其他特殊配置,请参考修改配置文件并重启 DataCap 服务。
+
+=== "配置"
+
+ | Field | Required | Default Value |
+ |:------:|:---------------------------------:|:-------------:|
+ | `Name` | :material-check-circle: { .red } | - |
+ | `Host` | :material-check-circle: { .red } | `hologres-cn-regison.aliyuncs.com` |
+ | `Port` | :material-check-circle: { .red } | `80` |
+
+=== "授权"
+
+ | Field | Required | Default Value |
+ |:----------:|:-----------------------:|:-------------:|
+ | `Username` | :material-close-circle: | - |
+ | `Password` | :material-close-circle: | - |
+
+=== "高级"
+
+ | Field | Required | Default Value |
+ |:----------:|:-----------------------:|:-------------:|
+ | `Database` | :material-close-circle: | - |
+
+#### 版本(验证)
+
+---
+
+!!! warning
+
+ 服务版本尚未测试,如果您有详细的测试并发现错误,请提交 [issues](https://github.com/EdurtIO/datacap/issues/new/choose)
+
+- [x] all
diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml
index 6ba6e60c..dbcfa271 100644
--- a/docs/mkdocs.yml
+++ b/docs/mkdocs.yml
@@ -149,6 +149,7 @@ nav:
- Connecting to connectors:
- reference/connectors/index.md
- JDBC:
+ - Hologres: reference/connectors/jdbc/hologres.md
- StarRocks: reference/connectors/jdbc/starrocks.md
- Apache Doris: reference/connectors/jdbc/doris.md
- DuckDB: reference/connectors/jdbc/duckdb.md
diff --git a/plugin/datacap-jdbc-hologres/pom.xml b/plugin/datacap-jdbc-hologres/pom.xml
new file mode 100644
index 00000000..f5f42136
--- /dev/null
+++ b/plugin/datacap-jdbc-hologres/pom.xml
@@ -0,0 +1,87 @@
+
+
+ 4.0.0
+
+ io.edurt.datacap
+ datacap
+ 1.9.0-SNAPSHOT
+ ../../pom.xml
+
+
+ datacap-jdbc-hologres
+ DataCap - Hologres
+
+
+ 42.6.0
+ jdbc-hologres
+
+
+
+ io.edurt.datacap
+ datacap-spi
+ provided
+
+
+ org.postgresql
+ postgresql
+ ${pgsql.version}
+
+
+ commons-beanutils
+ commons-beanutils
+
+
+ org.slf4j
+ slf4j-api
+
+
+ org.slf4j
+ slf4j-simple
+ test
+
+
+ org.jetbrains.kotlin
+ kotlin-reflect
+
+
+ org.testcontainers
+ testcontainers
+ test
+
+
+ org.testcontainers
+ postgresql
+ ${testcontainers.version}
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ ${assembly-plugin.version}
+
+ ${plugin.name}
+
+ ../../configure/assembly/assembly-plugin.xml
+
+ ../../dist/plugins/${plugin.name}
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
diff --git a/plugin/datacap-jdbc-hologres/src/main/kotlin/io/edurt/datacap/jdbc/hologres/HologresPlugin.kt b/plugin/datacap-jdbc-hologres/src/main/kotlin/io/edurt/datacap/jdbc/hologres/HologresPlugin.kt
new file mode 100644
index 00000000..bdfe2440
--- /dev/null
+++ b/plugin/datacap-jdbc-hologres/src/main/kotlin/io/edurt/datacap/jdbc/hologres/HologresPlugin.kt
@@ -0,0 +1,60 @@
+package io.edurt.datacap.jdbc.hologres
+
+import io.edurt.datacap.spi.Plugin
+import io.edurt.datacap.spi.adapter.JdbcAdapter
+import io.edurt.datacap.spi.connection.JdbcConfigure
+import io.edurt.datacap.spi.connection.JdbcConnection
+import io.edurt.datacap.spi.model.Configure
+import io.edurt.datacap.spi.model.Response
+import org.apache.commons.beanutils.BeanUtils
+import org.apache.commons.lang3.ObjectUtils
+import org.slf4j.LoggerFactory.getLogger
+
+class HologresPlugin : Plugin {
+ private val log = getLogger(HologresPlugin::class.java)
+
+ private var jdbcConfigure: JdbcConfigure? = null
+ private var jdbcConnection: JdbcConnection? = null
+ private var jdbcResponse: Response? = null
+ override fun name(): String {
+ return this.javaClass.simpleName.replace("Plugin", "")
+ }
+
+ override fun description(): String {
+ return String.format("Integrate %s data sources", this.name())
+ }
+
+ override fun connect(configure: Configure?) {
+ try {
+ log.info("Connecting to Hologres")
+ jdbcResponse = Response()
+ jdbcConfigure = JdbcConfigure()
+ BeanUtils.copyProperties(jdbcConfigure, configure)
+ jdbcConfigure!!.jdbcDriver = "org.postgresql.Driver"
+ jdbcConfigure!!.jdbcType = "postgresql"
+ jdbcConnection = object : JdbcConnection(jdbcConfigure, jdbcResponse) {}
+ } catch (ex: Exception) {
+ jdbcResponse!!.isConnected = false
+ jdbcResponse!!.message = ex.message
+ }
+ }
+
+ override fun execute(content: String?): Response {
+ if (ObjectUtils.isNotEmpty(jdbcConnection)) {
+ log.info("Execute hologres plugin logic started")
+ jdbcResponse = jdbcConnection?.response
+ val processor = JdbcAdapter(jdbcConnection)
+ jdbcResponse = processor.handlerExecute(content)
+ log.info("Execute hologres plugin logic end")
+ }
+ destroy()
+ return jdbcResponse!!
+ }
+
+ override fun destroy() {
+ if (ObjectUtils.isNotEmpty(jdbcConnection)) {
+ jdbcConnection?.destroy()
+ jdbcConnection = null
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugin/datacap-jdbc-hologres/src/main/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginModule.kt b/plugin/datacap-jdbc-hologres/src/main/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginModule.kt
new file mode 100644
index 00000000..76052bfe
--- /dev/null
+++ b/plugin/datacap-jdbc-hologres/src/main/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginModule.kt
@@ -0,0 +1,26 @@
+package io.edurt.datacap.jdbc.hologres
+
+import com.google.inject.multibindings.Multibinder
+import io.edurt.datacap.spi.AbstractPluginModule
+import io.edurt.datacap.spi.Plugin
+import io.edurt.datacap.spi.PluginModule
+import io.edurt.datacap.spi.PluginType
+
+class HologresPluginModule : AbstractPluginModule(), PluginModule {
+ override fun getName(): String {
+ return this.javaClass.simpleName.replace("PluginModule", "")
+ }
+
+ override fun getType(): PluginType {
+ return PluginType.JDBC
+ }
+
+ override fun get(): AbstractPluginModule {
+ return this
+ }
+
+ override fun configure() {
+ val plugin: Multibinder = Multibinder.newSetBinder(binder(), Plugin::class.java)
+ plugin.addBinding().to(HologresPlugin::class.java)
+ }
+}
\ No newline at end of file
diff --git a/plugin/datacap-jdbc-hologres/src/main/resources/META-INF/services/io.edurt.datacap.spi.PluginModule b/plugin/datacap-jdbc-hologres/src/main/resources/META-INF/services/io.edurt.datacap.spi.PluginModule
new file mode 100644
index 00000000..4eb88288
--- /dev/null
+++ b/plugin/datacap-jdbc-hologres/src/main/resources/META-INF/services/io.edurt.datacap.spi.PluginModule
@@ -0,0 +1 @@
+io.edurt.datacap.jdbc.hologres.HologresPluginModule
diff --git a/plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresContainer.kt b/plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresContainer.kt
new file mode 100644
index 00000000..fe69c928
--- /dev/null
+++ b/plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresContainer.kt
@@ -0,0 +1,18 @@
+package io.edurt.datacap.jdbc.hologres
+
+import org.testcontainers.containers.GenericContainer
+import org.testcontainers.utility.DockerImageName
+
+class HologresContainer : GenericContainer {
+ constructor() : super(DEFAULT_IMAGE_NAME)
+
+ constructor(dockerImageName: DockerImageName) : super(dockerImageName) {
+ dockerImageName.assertCompatibleWith(dockerImageName)
+ withExposedPorts(RPC_PORT)
+ }
+
+ companion object {
+ private val DEFAULT_IMAGE_NAME = DockerImageName.parse("postgres:latest")
+ const val RPC_PORT = 5432
+ }
+}
\ No newline at end of file
diff --git a/plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginModuleTest.kt b/plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginModuleTest.kt
new file mode 100644
index 00000000..750ca9cc
--- /dev/null
+++ b/plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginModuleTest.kt
@@ -0,0 +1,29 @@
+package io.edurt.datacap.jdbc.hologres
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Key;
+import com.google.inject.TypeLiteral;
+import io.edurt.datacap.spi.Plugin;
+import org.apache.commons.lang3.ObjectUtils
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Set;
+
+class HologresPluginModuleTest {
+ private var injector: Injector? = null
+
+ @Before
+ fun before() {
+ injector = Guice.createInjector(HologresPluginModule())
+ }
+
+ @Test
+ fun test() {
+ val plugin: Plugin? = injector?.getInstance(Key.get(object : TypeLiteral?>() {}))
+ ?.first { v -> v?.name().equals("Hologres") }
+ Assert.assertTrue(ObjectUtils.isNotEmpty(plugin))
+ }
+}
\ No newline at end of file
diff --git a/plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginTest.kt b/plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginTest.kt
new file mode 100644
index 00000000..1f3c2095
--- /dev/null
+++ b/plugin/datacap-jdbc-hologres/src/test/kotlin/io/edurt/datacap/jdbc/hologres/HologresPluginTest.kt
@@ -0,0 +1,75 @@
+package io.edurt.datacap.jdbc.hologres
+
+import com.google.inject.Guice
+import com.google.inject.Injector
+import com.google.inject.Key
+import com.google.inject.TypeLiteral
+import io.edurt.datacap.spi.Plugin
+import io.edurt.datacap.spi.model.Configure
+import io.edurt.datacap.spi.model.Response
+import org.apache.commons.lang3.ObjectUtils
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.slf4j.LoggerFactory.getLogger
+import org.testcontainers.containers.Network
+import org.testcontainers.lifecycle.Startables
+import org.testcontainers.shaded.com.google.common.collect.Lists
+import org.testcontainers.shaded.org.awaitility.Awaitility.given
+import java.util.*
+import java.util.Set
+import java.util.concurrent.TimeUnit
+
+class HologresPluginTest {
+ private val log = getLogger(HologresPluginTest::class.java)
+
+ private val host = "HologresCluster"
+ private val username = "root"
+ private val password = "12345678"
+ private var container: HologresContainer? = null
+ private var injector: Injector? = null
+ private var configure: Configure? = null
+
+ @Before
+ fun before() {
+ val network = Network.newNetwork()
+ container = HologresContainer()
+ ?.withNetwork(network)
+ ?.withNetworkAliases(host)
+ ?.withEnv("POSTGRES_USER", username)
+ ?.withEnv("POSTGRES_PASSWORD", password)
+ container?.portBindings = Lists.newArrayList(String.format("%s:%s", HologresContainer.RPC_PORT, HologresContainer.RPC_PORT))
+ Startables.deepStart(java.util.stream.Stream.of(container)).join()
+ log.info("Hologres container started")
+
+ given().ignoreExceptions()
+ .await()
+ .atMost(400, TimeUnit.SECONDS)
+
+ injector = Guice.createInjector(HologresPluginModule())
+ configure = Configure()
+ configure!!.host = "localhost"
+ configure!!.port = HologresContainer.RPC_PORT
+ configure!!.username = Optional.of(username)
+ configure!!.password = Optional.of(password)
+ configure!!.database = Optional.of("default")
+ }
+
+ @Test
+ fun test() {
+ val plugin: Plugin? = injector?.getInstance(Key.get(object : TypeLiteral?>() {}))
+ ?.first { v -> v?.name().equals("Hologres") }
+ if (ObjectUtils.isNotEmpty(plugin)) {
+ plugin?.connect(configure)
+ val sql = "SHOW DATABASES"
+ val response: Response = plugin!!.execute(sql)
+ log.info("================ plugin executed information =================")
+ if (!response.isSuccessful) {
+ log.error("Message: {}", response.message)
+ } else {
+ response.columns.forEach { column -> log.info(column.toString()) }
+ }
+ Assert.assertTrue(response.isSuccessful)
+ }
+ }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index c3e9c3d5..f5a2935d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,6 +59,7 @@
plugin/datacap-jdbc-trino
plugin/datacap-jdbc-doris
plugin/datacap-jdbc-starrocks
+ plugin/datacap-jdbc-hologres
executor/datacap-executor-example
executor/datacap-executor-seatunnel
shaded/datacap-shaded-ydb