PDGGK opened a new pull request, #125:
URL: https://github.com/apache/iotdb-extras/pull/125
Deploying the module into a real ThingsBoard for the first time surfaced two
defects the existing tests could not reach. Until now the module had been
compiled and integration-tested against ThingsBoard's types, but never run
inside a live instance — the gap recorded as the second layer of the fork
release notes.
Environment: `thingsboard/tb-node:4.3.1.2` against
`apache/iotdb:2.0.8-standalone`, module deployed per `USAGE.md`, driven through
ThingsBoard's own REST API.
## The attributes selector could never take effect
ThingsBoard gates its timeseries DAOs on `database.ts.type`, so for `ts` and
`ts_latest` it steps aside by itself. It offers **no equivalent for
attributes**: `JpaAttributeDao` is an unconditional `@Component` and registers
on every deployment, at every version.
So `AttributesDaoConflictGuard` always found a competing bean and failed
startup:
```
database.attributes.type=iotdb-table, but a non-IoTDB AttributesDao bean
'jpaAttributeDao'
is present; remove it or unset the IoTDB attributes selector
```
Its own advice cannot be followed — a `@Component` cannot be un-registered
from a properties file. The `USAGE.md` "separate, independent opt-in" was
therefore a startup failure on any stock ThingsBoard.
The guard now **withdraws** the competing definition rather than refusing to
start. It partitions the `AttributesDao` candidates first and mutates only once
a replacement of the same type is known to be registered — withdrawing without
one leaves zero `AttributesDao` beans, which is an outage rather than a
degraded mode. It runs at `HIGHEST_PRECEDENCE` (the only one of these
post-processors that mutates), carries the resolved type out of partitioning so
the WARN cannot NPE after a mutation, and logs what it removed:
```
WARN Removed ThingsBoard bean 'jpaAttributeDao'
(org.thingsboard.server.dao.sql.attributes.JpaAttributeDao) because
database.attributes.type=iotdb-table selects the IoTDB attributes
backend; ThingsBoard
provides no configuration switch for attributes, so the conflicting
bean is deregistered
rather than left to conflict.
```
Our own DAO bean also had to lose `@ConditionalOnMissingBean(type =
AttributesDao)`: that condition is evaluated while configuration classes are
parsed, strictly before the post-processor runs, so on a stock ThingsBoard it
skipped our bean on every deployment. Exclusivity is now enforced by the guard,
which is the only place that can enforce it.
## A runtime dependency was demoted out of the runtime classpath
`iotdb-thrift-commons` was declared at test scope, with a comment describing
it as "a transitive runtime dependency of iotdb-session" — which is precisely
what the declaration broke, since a direct declaration wins under Maven's
nearest-definition rule. It carries `TEndPoint`, which the session pool needs
at runtime:
```
Caused by: java.lang.NoClassDefFoundError:
org/apache/iotdb/isession/pool/ITableSessionPool
Caused by: java.lang.ClassNotFoundException:
org.apache.iotdb.common.rpc.thrift.TEndPoint
```
Verified with `dependency:build-classpath -DincludeScope=runtime`: absent
before, present after. `dependency:analyze` cannot see a reflective/transitive
runtime use and reports the compile scope as a test-only dependency, so the
finding is suppressed with its reason rather than silenced by restoring the
broken scope.
## Verification
`mvn -P with-thingsboard,iotdb-table-it verify` — **194 unit tests + 58
integration tests**, rat / checkstyle / spotless / dependency-analyze /
enforcer clean.
End to end on 4.3.1.2, through ThingsBoard's REST API: telemetry and
attributes written and confirmed in IoTDB; five read shapes correct — raw
range, latest, attributes, fixed-window aggregation (AVG and COUNT arithmetic
exact), and calendar aggregation in a non-UTC zone. ThingsBoard's own internal
telemetry flows through the module as well, so the whole platform's persistence
is served by it.
## Points I'd appreciate review on
- **The guard's semantics changed, and this is the part I would most like a
second opinion on.** In #113 it was reviewed as "fail loudly on a conflict"; it
is now "withdraw the conflicting bean and log". My reasoning is that we are
supplying a switch ThingsBoard does not have rather than fighting its design,
and that the withdrawal sits behind two explicit properties and a WARN. But how
far an extension module may go in mutating its host's bean definitions is a
judgement I do not want to make alone. The alternative is to retreat — mark
attributes as pending ThingsBoard-side selector support, which is honest but
gives up the capability. **I am happy to take either, or to take this to dev@
first if that is the better route.**
- **The `dependency:analyze` suppression.** It is the honest option as far
as I can tell, but it does mean a static check no longer guards that
dependency. If there is a way to make the runtime use visible to the analyzer
instead, I would rather do that.
- **Guard test coverage is partial.** Four tests where there were none:
withdrawal, the zero-replacement refusal, the no-op path, ordering. Not yet
covered: a bean whose type will not resolve, a factory that cannot withdraw,
the WARN assertion (the module's test classpath has no logging backend), and an
`ApplicationContextRunner` pair for the selector-off and end-to-end wiring
cases. Happy to add them here if you would like them before merge.
Happy to iterate.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]