EN Upgrades and Migration - AlanDevise/TsGate GitHub Wiki
2.1.3 is published through the GitHub source/tag and Maven Central; same-SHA CI and public artifact verification passed. Current coordinates: 2.1.3; see 2.1.3 release notes.
Before upgrading, review dynamically constructed filters: comparisons require exactly one operand, BETWEEN two, and IN at least one. Direct-model null operands and non-finite Float/Double values now fail with ARGUMENT_ERROR before I/O. Optional fluent-builder normalization remains unchanged; the literal string "null" remains an ordinary string. Count ignores pagination/cursors in a private copy, and the SPI default count(null) reports ARGUMENT_ERROR.
IoTDB groups table names by Locale.ROOT lowercase physical identity before checking complete-batch column roles/types. Conflicting variants now fail with METADATA_ERROR / NOT_COMMITTED before borrowing a session; compatible variants retain table-local row order and existing Tablet splitting. Use unique native-query output aliases: exact duplicate SDK columns or InfluxDB 3 JSON object keys now fail the entire query/count/executeQuery with QUERY_ERROR. Case-distinct result keys and the existing loose DTO mapping remain unchanged.
Direct adapter batchWriteDetailed / batchWrite rejects an obviously oversized reported collection size before copying or traversing records, then rechecks the snapshot. Lifecycle checks still come first and ready-state null/empty batches remain successful. Rejection is ARGUMENT_ERROR / NOT_COMMITTED with zero I/O. Split batches explicitly or assess the existing positive max-batch-records setting; this adds no resource-budget setting or hard memory guarantee for arbitrary custom collections.
Central consumers upgrading from 2.1.0 also receive the earlier GitHub-only 2.1.1/2.1.2 fixes: numeric cursor boundaries and IoTDB column identity, HTTP redirect commit reporting, missing InfluxDB 3 JSON errors, aggregate output-name checks, the configurable 64 MiB complete HTTP batch budget and POJO read-plan caching. These are inherited changes, not additions first made in 2.1.3. Review 2.1.1 notes and 2.1.2 notes, including final HTTP endpoint configuration and explicit batch splitting.
Version 2.1.2 keeps the public APIs, Java 17 baseline, client versions and TGTemplate → TSDBAdapter → backend design. It fixes automatic HTTP redirects, missing InfluxDB 3 JSON responses and aggregate result-name collisions; it adds a combined HTTP application-batch byte budget and class-lifecycle POJO read-plan reuse.
- Configure the final HTTP endpoint. A deployment that previously relied on a 3xx response must route to its final service or ingress before upgrading.
- HTTP application batches default to a 64 MiB combined prepared UTF-8 payload budget. Split an oversized application batch, or explicitly raise positive
max-batch-bytesafter assessing memory. Requests are never submitted before full-batch preflight completes. - Choose distinct aggregate aliases and grouping tag names after backend normalization.
window_startis reserved only for a generated time-window output. IoTDB case variants collide; Influx case-distinct names remain valid. InfluxDB 1.x/OpenGemini additionally reserve the implicit aggregate response columntime, whileTimestays distinct; this does not reservetimeon the two SQL adapters. - An absent or blank InfluxDB 3 HTTP response now fails as
QUERY_ERROR; a valid[]remains empty success. POJO mapping priority and conversion semantics remain unchanged.
Version 2.1.2 uses GitHub-only distribution; package and reports are linked from v2.1.2. At the time of that release, Maven Central remained at 2.1.0. Install aligned 2.1.2 modules/BOM from the verified v2.1.2 source before declaring those coordinates. Historical 2.1.2 verification and distribution are recorded in 2.1.2 release notes. Historical 2.1.0/2.1.1 evidence is retained separately.
All four backends are disabled by default. Configure the chosen backend directly in application.yml and explicitly set its enable flag to true. No spring.profiles.active option or enable: false entries for other backends are required. Missing or false flags keep a backend inactive even when connection settings are present. Spring profiles are optional application configuration tools, not a TsGate requirement.
Database servers, official Java clients and TsGate have independent versions. Do not automatically update client dependencies whenever a database release appears, or copy the server version number into the component version.
- Read the official release notes and migration guide. Check changes to protocols, authentication, SQL dialects, data types, batch-write error semantics and the Java baseline.
- Pin the new client and Docker image versions on an upgrade branch. When rebuilding TsGate, update
iotdb.versionfor IoTDB; consuming applications instead use the artifact-level dependency override described below. For InfluxDB 3, updateinfluxdb3-java.versionand review Arrow / Netty / gRPC / OkHttp / Jackson. For InfluxDB 1.x, update itsinfluxdb-javadependency and review OkHttp / Jackson. Inspect the final dependency tree. - Test both the current minimum supported server and the target server: writes/queries, native clients, pagination counts, nulls and precision, partial batch failures, recovery after disconnect, concurrent closure, DST windows and row/byte limits. Then run the documented JDK / Boot consumer matrix.
- Adapt SQL or protocol changes in the backend module first. Retaining an old-version branch or adding capability detection requires tests against both versions. If old-version support cannot be maintained, explicitly raise the baseline and document migration steps in both Wiki languages.
- Choose the component version using the table below, keeping all current source JAR modules and the standalone BOM aligned. Update compatibility, dependency examples, configuration and change history in both Wiki languages, together with both repository overview READMEs, before release. Retain older artifacts, validate application upgrades in an independent environment and prepare a rollback.
| Component version | When to use it | Example |
|---|---|---|
PATCH 2.0.x
|
Fix preserving supported contracts, or a fully compatible dependency security patch verified by regression tests | Fixing a leaked result handle |
MINOR 2.x.0
|
Backward-compatible features, optional settings, additional supported servers or a lower Java baseline | Adding configurable query protection |
MAJOR 3.0.0
|
Incompatible public API/behavior changes, backend removal or a higher minimum Java / Boot / server version | Requiring Java 21 or dropping IoTDB 2.0.10 |
Even an upstream client PATCH release can affect SQL, memory or runtime dependencies. Select the TsGate version according to actual compatibility rather than mechanically copying upstream versioning.
TsGate artifacts use Maven groupId io.github.alandevise, associated with the maintainer’s AlanDevise GitHub identity. Version 2.1.0 aligns the parent, standalone tsgate-bom and nine JAR modules, including the new OpenGemini adapter/starter. Java packages are com.alandevise.tsgate.*. The historical 2.0.0 release contains seven JAR modules and remains available unchanged. Maven coordinates and Java package names serve different purposes.
- Strict cursors use backend physical-column identity consistently. InfluxDB 3 preserves case; IoTDB unquoted columns normalize to lowercase. Pass
nextCursorunchanged. Missing result cursor columns fail withQUERY_ERROR; invalid input cursor keys/order fail withARGUMENT_ERROR. - IoTDB cursor time conversion rejects fractional, non-finite and out-of-range numbers before SQL execution. Exact integral values such as
1.0are accepted. - IoTDB follows
NEW -> READY -> CLOSED: repeated init preserves the exposed pool proxy; failed init can be retried; close is terminal and waits for adapter operations. Create a new adapter/context after closure. Native session callers coordinate their own operations with shutdown. - Default aggregate aliases use
Locale.ROOT; explicit aliases are preserved. Map result classes are limited to Map, LinkedHashMap, HashMap and TreeMap; unsupported Map types fail before querying, including empty results. TreeMap provides key ordering rather than result-column ordering.
The default SPI method normalizeColumnIdentifier preserves case; backend implementations with folding rules can override it. See compatibility and validation for the exact tested combinations.
Application-facing annotations and query entry points use the TsGate TG prefix:
| Public type | Purpose | Package |
|---|---|---|
TGMeasurement |
Maps a POJO to a measurement/table | com.alandevise.tsgate.annotation |
TGTime |
Identifies the timestamp field | com.alandevise.tsgate.annotation |
TGTag |
Maps a tag field | com.alandevise.tsgate.annotation |
TGField |
Maps a value field | com.alandevise.tsgate.annotation |
TGTemplate |
Provides write and query operations | com.alandevise.tsgate.core |
TGQueryBuilder<T> |
Builds a query for an entity type | com.alandevise.tsgate.core |
TGTemplate.query(...) creates a TGQueryBuilder<T> for each query. Annotate entities with @TGMeasurement("telemetry") and the appropriate TGTime, TGTag and TGField annotations; see the complete POJO and injection example.
The active starter's default template bean is tgTemplate. Prefer type-based injection of TGTemplate; for name-based injection, use @Qualifier("tgTemplate") or @Resource(name = "tgTemplate"). A bare @Resource may select by field/property name. Select javax.annotation.Resource or jakarta.annotation.Resource according to the application's Spring generation.
An application-provided TGTemplate makes the starter back off by type. For an application-owned template, keep the chosen bean name and injection points consistent. For example, place this bean factory in an application configuration class:
import com.alandevise.tsgate.core.TGTemplate;
import com.alandevise.tsgate.adapter.TSDBAdapter;
import com.alandevise.tsgate.metadata.TSDBMetadataResolver;
import org.springframework.context.annotation.Bean;
@Bean
TGTemplate tgTemplate(TSDBAdapter adapter, TSDBMetadataResolver metadataResolver) {
return new TGTemplate(adapter, metadataResolver);
}YAML configuration uses the tsdb.* prefix. Public models and the adapter SPI include TSDBAdapter, TSDBRecord, TSDBQuery and TSDBException.
TsGate's default official org.apache.iotdb:iotdb-session SDK is 2.0.11. This client version is independent of the server version and TsGate's component version. See the exact completed checks on Compatibility and validation; upgrading the SDK alone does not certify every older or future server.
IoTDB's official Java Native API guide recommends matching client and server versions and warns that a newer client can fail against an older server. The older-server checks here are TsGate's specific tested combinations, not a general compatibility endorsement from Apache IoTDB.
When rebuilding TsGate itself, its parent POM's iotdb.version controls the SDK. For a business application that only depends on the starter, declaring an unrelated <iotdb.version> property in the application's POM does not replace the version already resolved by TsGate's dependency POM. Manage the actual artifact in the consuming application's dependencyManagement instead. The following example pins 2.0.11; replace the application-owned property value with another exact SDK release only after testing it:
<properties>
<app.iotdb-sdk.version>2.0.11</app.iotdb-sdk.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.iotdb</groupId>
<artifactId>iotdb-session</artifactId>
<version>${app.iotdb-sdk.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>io.github.alandevise</groupId>
<artifactId>tsgate-iotdb-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
</dependencies>Inspect the final graph in the business application, not only this repository:
mvn dependency:tree -Dverbose '-Dincludes=org.apache.iotdb:*,org.apache.tsfile:*,org.apache.thrift:*'
mvn help:effective-pomEnsure iotdb-session resolves to the selected version and inspect its isession, RPC, Thrift and TSFile dependencies, including omitted/conflicting entries. Start from the dependency versions declared by that SDK's official POM; an application BOM or a nearer dependency can still override them. If such a conflict requires managing another artifact, use the version required for that artifact by the selected SDK. Do not assign the SDK number to every IoTDB-family or TSFile artifact: TSFile and other dependencies have their own release numbers. The standalone tsgate-bom manages the default iotdb-session version; it deliberately lets the selected SDK supply its matching family, so overriding the SDK still requires this check. Maven's dependency-management rules explain the consumer override.
The dependency graphs checked for this change illustrate why those versions must not be flattened:
| Official Java SDK | IoTDB SDK family |
org.apache.tsfile:tsfile / common
|
org.apache.thrift:libthrift |
|---|---|---|---|
| 2.0.10 | 2.0.10 | 2.3.1 | 0.14.1 |
| 2.0.11 | 2.0.11 | 2.4.0 | 0.23.0 |
The resolved 2.0.11 graph also contains org.apache.thrift:libthrift:0.23.0. The archived graph is .local-test/2026-09-29-iotdb-sdk-upgrade/dependency-tree.log. These are the inspected combinations, not a rule that future SDKs must use these same transitive versions.
The only additional consumer SDK override validated in this change is 2.0.10, with the same TsGate JAR compiled against 2.0.11: on server 2.0.10, each setting passed 12 rows in one Tablet, Spring property binding and closure. This is a bounded consumer check, not full regression certification of that SDK. Do not copy the server version into the SDK property: older SDKs such as 2.0.5 lack the enableIoTDBRpcCompression builder method now required by this adapter and cannot be substituted directly without implementation changes and validation.
Keep Java 17 and the documented Spring Boot baseline, verify table-model API and runtime linkage, and rerun writes/queries, native pool usage, pagination, error semantics and lifecycle cases. Include a single actual Tablet with at least 10 rows for both relevant RPC-compression settings; tiny batches alone do not exercise the compatibility boundary. For an older incompatible server such as 2.0.2, explicitly set tsdb.iotdb.table.rpc-compression-enabled: false as shown in Configuration. Disabling Tablet RPC encoding is not a general guarantee that the server implements all APIs or SQL used by the adapter.
The default tsdb.influxdb.strict-cursor-sql: or retains existing SQL. For Core 3.0.0 / 3.0.3, explicitly configure union-all to use strict-cursor continuation; see Configuration and the exact server/strategy matrix. Omitted or blank configuration retains or; nonblank invalid values fail Spring binding. The adapter captures this setting at construction. There is no server-version probe, automatic fallback or HTTP 500 retry, and native SQL is never rewritten by the switch.
Before changing strategies or upgrading a server, regress both first and subsequent pages with equal timestamps, multiple tags, FIELD-first ordering, mixed directions, explicit projections, business filters and cursor/time-range boundaries. Check page contents and termination, not merely HTTP success. Retain row-limit, response-byte and invalid-cursor checks. Strict cursors combined with aggregation are rejected in union-all mode; ordinary aggregation retains its existing behavior.
UNION branches use the same business filters and mutually exclusive lexicographic comparisons, followed by one outer sort and page limit. Branches proven empty by the cursor time and explicit timeRange / startTime / endTime bounds are omitted; this does not analyze arbitrary filter expressions or rewrite native SQL. Up to one branch per completed cursor key can increase scans and sorting; assess realistic data volumes and time ranges before selecting this mode for newer servers that already support or. A client dependency upgrade is not required to select the SQL strategy. Passing one server/strategy combination does not certify other releases, other products such as Enterprise, or all native SQL.
Version 2.1.1 keeps the public API and architecture, adding exact result-time conversion, rejection of unusable time-page continuation, and IoTDB complete-batch physical-column preflight/value mapping. Fractional/non-finite/overflow result times cannot silently define a cursor; ambiguous IoTDB case variants cannot reach a database write. Existing valid inputs, lifecycle/configuration snapshots and backend commit-error distinctions remain.
Reusable test contracts and capability assertions precede new backend additions. Automatic CI selects affected Docker backends, with full OpenGemini 1.4.1/1.5.2 single-node and three-node/three-replica coverage for release tags/full manual runs. See Testing and publishing for selectors and gates.
Distribution: 2.1.1 is released only on GitHub. Install v2.1.1 source locally before declaring aligned 2.1.1 modules/BOM; do not expect this version from Maven Central; the last confirmed Central release at that time was 2.1.0. Exact changes and final evidence are in 2.1.1 release notes.
Version 2.1.0 incorporates the following fixes after 2.0.0 and adds OpenGemini support. Java 17, the documented Spring Boot/client baselines, and the Template → adapter SPI → backend design are retained. See 2.1.0 release notes for the exact backend scope and validation status.
- Strict cursor input is preserved until validation, so null-valued, blank, additional or normalized-duplicate keys fail with
ARGUMENT_ERRORinstead of being discarded. Null/empty maps still mean the first page. - InfluxDB 3 and IoTDB starters now honor
fail-fast=falsefor resource initialization failures with unavailable optional native clients, matching InfluxDB 1.x. Manual initialization retry does not automatically recreate an unavailable Spring native-client bean. - All adapters capture complete configuration snapshots at construction. Move any Properties mutation before construction; create a new instance for configuration changes or corrections. Transient initialization retry and IoTDB recovery keep the original snapshot.
- Direct structured query calls consistently reject null queries, nonpositive limits, negative offsets and reversed time ranges before I/O. Count still ignores pagination/cursors; the shared default count implementation also classifies a null query as
ARGUMENT_ERROR. - OpenGemini adapter/starter and BOM integration target 1.4.1/1.5.2 default-engine single nodes and three-node/three-replica clusters. Complete-batch measurement/integer checks, exact missing-measurement handling, compatible native health/version, lifecycle and bounded queries are documented in OpenGemini integration.
See Configuration, Pagination and validation evidence for optional injection, configuration guidance and the exact tested source combinations.
2.0.0 is TsGate's first public release. It provides:
- A standalone
tsgate-bom, independent IoTDB / InfluxDB 3 / InfluxDB 1.x adapters and Spring Boot starters, and theTG*API described above. - A Java 17 compile/runtime baseline without preview features and a Spring Boot 2.7.18 build baseline. Exact runtime and database combinations are listed in compatibility and validation.
- IoTDB Java SDK 2.0.11 and
tsdb.iotdb.table.rpc-compression-enabled, defaulting totrue. Older incompatible servers such as 2.0.2 require explicitfalse. The setting controls Tablet RPC payload encoding, not Thrift transport or disk compression, and applies to initial and replacement pools. - InfluxDB 3
tsdb.influxdb.strict-cursor-sql: or|union-all, defaulting toor. Explicitunion-allsupports structured strict-cursor continuation on the verified Core 3.0.0 / 3.0.3 combinations. It preserves key completion, ordering, one-row probing and query limits, rejects strict cursors combined with aggregation, and does not rewrite native SQL or retry queries automatically. - Explicit conversion errors for invalid numeric text, integer overflow and invalid boolean text; native-query row limits and streaming InfluxDB response-byte limits. Paginate large results or configure suitable limits.
- Idempotent InfluxDB initialization, retryable initialization failure and terminal closure that waits for adapter operations. Create a new instance after close.
- Local-calendar day windows for IoTDB / InfluxDB 3 regional time zones. Regional zones require a time range; sub-day windows crossing offset changes are rejected. InfluxDB 1.x does not support regional calendar-day windows, and all its window queries require explicit start and end times.
- A default database of
tsdbfor all three backends, configurable through the chosen backend'sdatabaseproperty. IoTDB / InfluxDB 1.x require the target database to exist; explicitly blank values fail validation. Configuration does not create or migrate databases. - Explicit backend activation with
enable: true. Missing flags and connection-only configuration leave the backend inactive; other backends need no false flags. Multiple active backends or invalid flags fail configuration. - English Javadoc and source comments, bilingual Wiki usage documentation, concise English and Chinese README overviews, portable test sources and CI configuration. Source/Javadoc artifacts include license materials; release commands are documented in testing and publishing.
- Apache License 2.0 for project-owned code, with copyright attribution in
NOTICE. Third-party components retain their own licenses.
Project-owned code is licensed under the Apache License 2.0; copyright attribution is retained in NOTICE. Use, modification and distribution are subject to the license terms. Third-party dependencies retain their own licenses. The standard text comes from the Apache Software Foundation.
Documentation maintenance covers both repository overview READMEs and both Wiki languages. Keep API behavior, configuration, limits, error semantics, compatibility, upgrades, examples and change history synchronized with adapter changes. See testing and publishing for test and release commands.
← Compatibility, validation and readiness
TsGate 2.1.0 includes the independent OpenGemini adapter and starter. See OpenGemini integration for configuration, default-engine limits and exact-version testing, and 2.1.0 release notes for release changes.