diff --git a/deploy/portainer/docker-compose.yml b/deploy/portainer/docker-compose.yml
index 3e71b29a..0991992f 100644
--- a/deploy/portainer/docker-compose.yml
+++ b/deploy/portainer/docker-compose.yml
@@ -84,6 +84,15 @@ services:
EVENT_FILE_STORE_ENABLED: ${EVENT_FILE_STORE_ENABLED:-true}
EVENT_FILE_STORE_PATH: /event-store/
EVENT_FILE_STORE_ZONE_ID: ${EVENT_FILE_STORE_ZONE_ID:-Asia/Shanghai}
+ TDENGINE_HISTORY_ENABLED: ${TDENGINE_HISTORY_ENABLED:-true}
+ TDENGINE_HISTORY_DATABASE: ${TDENGINE_HISTORY_DATABASE:-vehicle_history}
+ TDENGINE_JDBC_URL: ${TDENGINE_JDBC_URL:-jdbc:TAOS-RS://tdengine:6041/vehicle_history}
+ TDENGINE_USERNAME: ${TDENGINE_USERNAME:-root}
+ TDENGINE_PASSWORD: ${TDENGINE_PASSWORD:-taosdata}
+ TDENGINE_MAX_POOL_SIZE: ${TDENGINE_MAX_POOL_SIZE:-32}
+ TDENGINE_MIN_IDLE: ${TDENGINE_MIN_IDLE:-0}
+ TDENGINE_CONNECTION_TIMEOUT_MILLIS: ${TDENGINE_CONNECTION_TIMEOUT_MILLIS:-5000}
+ TDENGINE_INITIALIZATION_FAIL_TIMEOUT_MILLIS: ${TDENGINE_INITIALIZATION_FAIL_TIMEOUT_MILLIS:--1}
ports:
- "${VEHICLE_HISTORY_HTTP_PORT:-20200}:20200"
volumes:
diff --git a/modules/apps/vehicle-history-app/src/main/resources/application.yml b/modules/apps/vehicle-history-app/src/main/resources/application.yml
index 7f38d578..b6ec8d2e 100644
--- a/modules/apps/vehicle-history-app/src/main/resources/application.yml
+++ b/modules/apps/vehicle-history-app/src/main/resources/application.yml
@@ -69,6 +69,14 @@ lingniu:
tdengine-history:
enabled: ${TDENGINE_HISTORY_ENABLED:false}
database: ${TDENGINE_HISTORY_DATABASE:vehicle_history}
+ jdbc-url: ${TDENGINE_JDBC_URL:jdbc:TAOS-RS://${TDENGINE_HOST:127.0.0.1}:${TDENGINE_PORT:6041}/${TDENGINE_HISTORY_DATABASE:vehicle_history}}
+ username: ${TDENGINE_USERNAME:root}
+ password: ${TDENGINE_PASSWORD:taosdata}
+ driver-class-name: ${TDENGINE_DRIVER_CLASS_NAME:com.taosdata.jdbc.rs.RestfulDriver}
+ maximum-pool-size: ${TDENGINE_MAX_POOL_SIZE:16}
+ minimum-idle: ${TDENGINE_MIN_IDLE:0}
+ connection-timeout-millis: ${TDENGINE_CONNECTION_TIMEOUT_MILLIS:5000}
+ initialization-fail-timeout-millis: ${TDENGINE_INITIALIZATION_FAIL_TIMEOUT_MILLIS:-1}
event-history:
enabled: true
vehicle-state:
diff --git a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppCompositionTest.java b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppCompositionTest.java
index 0c54f2df..db4034d8 100644
--- a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppCompositionTest.java
+++ b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppCompositionTest.java
@@ -8,6 +8,8 @@ import com.lingniu.ingest.eventhistory.EventHistoryEnvelopeIngestor;
import com.lingniu.ingest.eventhistory.Gb32960DecodedFrameService;
import com.lingniu.ingest.eventhistory.Gb32960FrameController;
import com.lingniu.ingest.eventhistory.config.EventHistoryAutoConfiguration;
+import com.lingniu.ingest.eventhistory.Jt808LocationHistoryController;
+import com.lingniu.ingest.eventhistory.TelemetryFieldHistoryController;
import com.lingniu.ingest.protocol.gb32960.codec.Gb32960MessageDecoder;
import com.lingniu.ingest.protocol.gb32960.config.Gb32960AutoConfiguration;
import com.lingniu.ingest.protocol.gb32960.inbound.Gb32960NettyServer;
@@ -78,6 +80,8 @@ class VehicleHistoryAppCompositionTest {
assertThat(context).hasSingleBean(Gb32960MessageDecoder.class);
assertThat(context).hasSingleBean(Gb32960DecodedFrameService.class);
assertThat(context).hasSingleBean(Gb32960FrameController.class);
+ assertThat(context).hasSingleBean(Jt808LocationHistoryController.class);
+ assertThat(context).hasSingleBean(TelemetryFieldHistoryController.class);
assertThat(context).doesNotHaveBean(Gb32960NettyServer.class);
});
}
diff --git a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppDefaultsTest.java b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppDefaultsTest.java
index 38c47d24..92aa42ab 100644
--- a/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppDefaultsTest.java
+++ b/modules/apps/vehicle-history-app/src/test/java/com/lingniu/ingest/historyapp/VehicleHistoryAppDefaultsTest.java
@@ -26,6 +26,16 @@ class VehicleHistoryAppDefaultsTest {
.containsEntry("lingniu.ingest.event-file-store.enabled", "${EVENT_FILE_STORE_ENABLED:true}")
.containsEntry("lingniu.ingest.tdengine-history.enabled", "${TDENGINE_HISTORY_ENABLED:false}")
.containsEntry("lingniu.ingest.tdengine-history.database", "${TDENGINE_HISTORY_DATABASE:vehicle_history}")
+ .containsEntry(
+ "lingniu.ingest.tdengine-history.jdbc-url",
+ "${TDENGINE_JDBC_URL:jdbc:TAOS-RS://${TDENGINE_HOST:127.0.0.1}:${TDENGINE_PORT:6041}/${TDENGINE_HISTORY_DATABASE:vehicle_history}}")
+ .containsEntry("lingniu.ingest.tdengine-history.username", "${TDENGINE_USERNAME:root}")
+ .containsEntry("lingniu.ingest.tdengine-history.password", "${TDENGINE_PASSWORD:taosdata}")
+ .containsEntry(
+ "lingniu.ingest.tdengine-history.driver-class-name",
+ "${TDENGINE_DRIVER_CLASS_NAME:com.taosdata.jdbc.rs.RestfulDriver}")
+ .containsEntry("lingniu.ingest.tdengine-history.maximum-pool-size", "${TDENGINE_MAX_POOL_SIZE:16}")
+ .containsEntry("lingniu.ingest.tdengine-history.minimum-idle", "${TDENGINE_MIN_IDLE:0}")
.containsEntry("lingniu.ingest.event-history.enabled", true)
.containsEntry("lingniu.ingest.vehicle-state.enabled", false)
.containsEntry("lingniu.ingest.vehicle-stat.enabled", false)
diff --git a/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/config/EventHistoryAutoConfiguration.java b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/config/EventHistoryAutoConfiguration.java
index edcb8c12..339ff4a8 100644
--- a/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/config/EventHistoryAutoConfiguration.java
+++ b/modules/services/event-history-service/src/main/java/com/lingniu/ingest/eventhistory/config/EventHistoryAutoConfiguration.java
@@ -14,6 +14,7 @@ import com.lingniu.ingest.protocol.gb32960.codec.Gb32960MessageDecoder;
import com.lingniu.ingest.protocol.gb32960.config.Gb32960AutoConfiguration;
import com.lingniu.ingest.sink.archive.config.SinkArchiveAutoConfiguration;
import com.lingniu.ingest.sink.archive.config.SinkArchiveProperties;
+import com.lingniu.ingest.tdenginehistory.config.TdengineHistoryAutoConfiguration;
import com.lingniu.ingest.tdenginehistory.TdengineHistoryReader;
import com.lingniu.ingest.tdenginehistory.TdengineHistoryWriter;
import org.springframework.boot.autoconfigure.AutoConfiguration;
@@ -40,7 +41,11 @@ import java.nio.file.Path;
* Kafka consumer 是否启动还取决于 {@code lingniu.ingest.sink.mq.consumer.enabled=true}。
*/
@AutoConfiguration
-@AutoConfigureAfter({Gb32960AutoConfiguration.class, SinkArchiveAutoConfiguration.class})
+@AutoConfigureAfter({
+ Gb32960AutoConfiguration.class,
+ SinkArchiveAutoConfiguration.class,
+ TdengineHistoryAutoConfiguration.class
+})
@ConditionalOnProperty(prefix = "lingniu.ingest.event-history", name = "enabled", havingValue = "true")
public class EventHistoryAutoConfiguration {
diff --git a/modules/sinks/tdengine-history-store/pom.xml b/modules/sinks/tdengine-history-store/pom.xml
index 1612dcb0..f5798f52 100644
--- a/modules/sinks/tdengine-history-store/pom.xml
+++ b/modules/sinks/tdengine-history-store/pom.xml
@@ -24,6 +24,14 @@
org.springframework.boot
spring-boot-autoconfigure
+
+ com.taosdata.jdbc
+ taos-jdbcdriver
+
+
+ com.zaxxer
+ HikariCP
+
org.springframework.boot
spring-boot-configuration-processor
diff --git a/modules/sinks/tdengine-history-store/src/main/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryAutoConfiguration.java b/modules/sinks/tdengine-history-store/src/main/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryAutoConfiguration.java
index b808308e..2d612fb3 100644
--- a/modules/sinks/tdengine-history-store/src/main/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryAutoConfiguration.java
+++ b/modules/sinks/tdengine-history-store/src/main/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryAutoConfiguration.java
@@ -6,6 +6,8 @@ import com.lingniu.ingest.tdenginehistory.TdengineHistoryReader;
import com.lingniu.ingest.tdenginehistory.TdengineHistoryWriter;
import com.lingniu.ingest.tdenginehistory.TdengineJdbcHistoryReader;
import com.lingniu.ingest.tdenginehistory.TdengineJdbcHistoryWriter;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
@@ -39,6 +41,26 @@ public class TdengineHistoryAutoConfiguration {
return new TdengineHistoryStatements(schema);
}
+ @Bean
+ @ConditionalOnMissingBean(DataSource.class)
+ @ConditionalOnProperty(
+ prefix = "lingniu.ingest.tdengine-history",
+ name = "enabled",
+ havingValue = "true")
+ public DataSource tdengineDataSource(TdengineHistoryProperties properties) {
+ HikariConfig config = new HikariConfig();
+ config.setPoolName("tdengine-history");
+ config.setDriverClassName(properties.getDriverClassName());
+ config.setJdbcUrl(properties.getJdbcUrl());
+ config.setUsername(properties.getUsername());
+ config.setPassword(properties.getPassword());
+ config.setMaximumPoolSize(Math.max(1, properties.getMaximumPoolSize()));
+ config.setMinimumIdle(Math.max(0, Math.min(properties.getMinimumIdle(), properties.getMaximumPoolSize())));
+ config.setConnectionTimeout(Math.max(250, properties.getConnectionTimeoutMillis()));
+ config.setInitializationFailTimeout(properties.getInitializationFailTimeoutMillis());
+ return new HikariDataSource(config);
+ }
+
@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(DataSource.class)
diff --git a/modules/sinks/tdengine-history-store/src/main/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryProperties.java b/modules/sinks/tdengine-history-store/src/main/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryProperties.java
index 03009ee2..d19a28eb 100644
--- a/modules/sinks/tdengine-history-store/src/main/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryProperties.java
+++ b/modules/sinks/tdengine-history-store/src/main/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryProperties.java
@@ -15,6 +15,25 @@ public class TdengineHistoryProperties {
*/
private String database = "vehicle_history";
+ /**
+ * TDengine RESTful JDBC 地址。默认走 6041,部署时可用 TDENGINE_JDBC_URL 覆盖。
+ */
+ private String jdbcUrl;
+
+ private String username = "root";
+
+ private String password = "taosdata";
+
+ private String driverClassName = "com.taosdata.jdbc.rs.RestfulDriver";
+
+ private int maximumPoolSize = 16;
+
+ private int minimumIdle = 0;
+
+ private long connectionTimeoutMillis = 5000;
+
+ private long initializationFailTimeoutMillis = -1;
+
public boolean isEnabled() {
return enabled;
}
@@ -30,4 +49,71 @@ public class TdengineHistoryProperties {
public void setDatabase(String database) {
this.database = database;
}
+
+ public String getJdbcUrl() {
+ if (jdbcUrl == null || jdbcUrl.isBlank()) {
+ return "jdbc:TAOS-RS://127.0.0.1:6041/" + database;
+ }
+ return jdbcUrl;
+ }
+
+ public void setJdbcUrl(String jdbcUrl) {
+ this.jdbcUrl = jdbcUrl;
+ }
+
+ public String getUsername() {
+ return username;
+ }
+
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
+ public String getPassword() {
+ return password;
+ }
+
+ public void setPassword(String password) {
+ this.password = password;
+ }
+
+ public String getDriverClassName() {
+ return driverClassName;
+ }
+
+ public void setDriverClassName(String driverClassName) {
+ this.driverClassName = driverClassName;
+ }
+
+ public int getMaximumPoolSize() {
+ return maximumPoolSize;
+ }
+
+ public void setMaximumPoolSize(int maximumPoolSize) {
+ this.maximumPoolSize = maximumPoolSize;
+ }
+
+ public int getMinimumIdle() {
+ return minimumIdle;
+ }
+
+ public void setMinimumIdle(int minimumIdle) {
+ this.minimumIdle = minimumIdle;
+ }
+
+ public long getConnectionTimeoutMillis() {
+ return connectionTimeoutMillis;
+ }
+
+ public void setConnectionTimeoutMillis(long connectionTimeoutMillis) {
+ this.connectionTimeoutMillis = connectionTimeoutMillis;
+ }
+
+ public long getInitializationFailTimeoutMillis() {
+ return initializationFailTimeoutMillis;
+ }
+
+ public void setInitializationFailTimeoutMillis(long initializationFailTimeoutMillis) {
+ this.initializationFailTimeoutMillis = initializationFailTimeoutMillis;
+ }
}
diff --git a/modules/sinks/tdengine-history-store/src/test/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryAutoConfigurationTest.java b/modules/sinks/tdengine-history-store/src/test/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryAutoConfigurationTest.java
index 58d8ba0e..8117f110 100644
--- a/modules/sinks/tdengine-history-store/src/test/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryAutoConfigurationTest.java
+++ b/modules/sinks/tdengine-history-store/src/test/java/com/lingniu/ingest/tdenginehistory/config/TdengineHistoryAutoConfigurationTest.java
@@ -3,6 +3,7 @@ package com.lingniu.ingest.tdenginehistory.config;
import com.lingniu.ingest.tdenginehistory.TdengineHistorySchema;
import com.lingniu.ingest.tdenginehistory.TdengineHistoryReader;
import com.lingniu.ingest.tdenginehistory.TdengineHistoryWriter;
+import com.zaxxer.hikari.HikariDataSource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
@@ -21,6 +22,7 @@ class TdengineHistoryAutoConfigurationTest {
void staysOffByDefault() {
contextRunner.run(context -> {
assertThat(context).doesNotHaveBean(TdengineHistorySchema.class);
+ assertThat(context).doesNotHaveBean(DataSource.class);
assertThat(context.getBean(TdengineHistoryProperties.class).isEnabled()).isFalse();
});
}
@@ -53,4 +55,27 @@ class TdengineHistoryAutoConfigurationTest {
.withPropertyValues("lingniu.ingest.tdengine-history.enabled=true")
.run(context -> assertThat(context).hasSingleBean(TdengineHistoryReader.class));
}
+
+ @Test
+ void createsTdengineDataSourceWhenEnabled() {
+ contextRunner
+ .withPropertyValues(
+ "lingniu.ingest.tdengine-history.enabled=true",
+ "lingniu.ingest.tdengine-history.jdbc-url=jdbc:TAOS-RS://tdengine:6041/vehicle_history",
+ "lingniu.ingest.tdengine-history.username=root",
+ "lingniu.ingest.tdengine-history.password=secret",
+ "lingniu.ingest.tdengine-history.maximum-pool-size=24",
+ "lingniu.ingest.tdengine-history.minimum-idle=3",
+ "lingniu.ingest.tdengine-history.initialization-fail-timeout-millis=-1")
+ .run(context -> {
+ assertThat(context).hasSingleBean(DataSource.class);
+ HikariDataSource dataSource = context.getBean(HikariDataSource.class);
+ assertThat(dataSource.getJdbcUrl()).isEqualTo("jdbc:TAOS-RS://tdengine:6041/vehicle_history");
+ assertThat(dataSource.getUsername()).isEqualTo("root");
+ assertThat(dataSource.getMaximumPoolSize()).isEqualTo(24);
+ assertThat(dataSource.getMinimumIdle()).isEqualTo(3);
+ assertThat(context).hasSingleBean(TdengineHistoryWriter.class);
+ assertThat(context).hasSingleBean(TdengineHistoryReader.class);
+ });
+ }
}
diff --git a/pom.xml b/pom.xml
index 3e20a6fa..f00e4a3e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -65,6 +65,7 @@
1.42.1
1.3.3
1.1.3
+ 3.8.4
2.8.17
1.18.34
5.11.3
@@ -303,6 +304,11 @@
duckdb_jdbc
${duckdb.version}
+
+ com.taosdata.jdbc
+ taos-jdbcdriver
+ ${taos-jdbcdriver.version}
+
org.springdoc
springdoc-openapi-starter-webmvc-ui