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:   StarRocks +   + + Hologres

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