five drivers carried private bytesToHex copies and three carried
hexToBytes variants, while mbus/dlt645 frames each implemented the same
sum checksum:
- codecutil.bytesToHex now uses hexformat uppercase, matching what all
five private copies already emitted (zero display change)
- codecutil.hexToBytes added: whitespace-tolerant, blank-to-empty,
mixed-case input
- codecutil.sumChecksum added as the shared mbus/dlt645 frame checksum
and both frame classes delegate to it
- dlt645's inline hex loop replaced by codecutil.hexTobytes
- fins' private bcd copy kept deliberately: codecutil's bcd variant
strips leading zeros, a different protocol semantic
a live-stack sweep of all 36 drivers surfaced five sdk-level defects
that left reads dead or the whole fleet unbootable:
- drop the empty spring.main stub in the shared driver profile; the
boot 4.1 binder rejects null-valued keys and every driver died at
startup with a bind exception
- rename the schedule enable flag to enable to match what every driver
application.yml actually spells; with the old enabled key the read
and custom quartz jobs were silently never scheduled
- treat proto3 zero-versions as unset when reconciling registration
so a driver restart re-registers instead of failing the optimistic
lock with 'driver version conflict'
- ignore the driver's own registration event that can be consumed
before applymetadata finishes instead of logging an error
- initialize jdbc/serial connection maps eagerly: the registration
event handler invalidates pools and nped on a lazy-null map
- ble: exclude the guava 18 pin dragged in by bluetooth-manager
- kafka: use the starter (boot 4 split autoconfigurations out of the
bare jar) and read the compose-provided bootstrap variable
- lwm2m: pin californium to the 3.x api leshan m14 needs and
configure an explicit coap endpoint
- mqtt: replace the orphaned spring-integration gateway with a paho
publisher so the send path exists again
- boot sweep result: 36/36 drivers start, 0 errors
- migrate auth, manager, data, and agentic persistence to R2DBC
- hard cut pagination, facade, gateway, web, and CLI contracts
- remove legacy database and TSDB adapters and document validation gates
BREAKING CHANGE: platform persistence now requires PostgreSQL 18 with TimescaleDB and the new reactive API contracts.
- Spring Boot 4.0.7 -> 4.1.1, Spring Cloud 2025.1.2 -> 2025.1.3,
Spring AI 2.0.0 -> 2.0.1, springdoc 3.0.3 -> 3.1.0
- Migrate gRPC starters to the Boot-owned spring-boot-starter-grpc-client/server
line (org.springframework.grpc starter stops at 1.0.3 and mixes badly with the
spring-grpc-core 1.1.1 managed by the Boot 4.1 BOM), and move the
spring.grpc.channels.* YAML keys to the new spring.grpc.channel.* format
- Refresh driver protocol libraries (modbus4j 3.1.0, jSerialComm 2.11.4,
bacnet4j 6.1.1, gurux-dlms 4.0.96, j60870 1.8.0, snmp4j 3.13.1) and drop the
flow-control overrides removed from the modbus4j SerialPortWrapper interface
- Refresh jackson 2.x/3.x, protobuf, okhttp, micrometer, oshi, sqlite-jdbc,
swagger-core, instancio, mockito, logstash-logback-encoder 9.0 and the
graalvm native plugin; keep commons-io (broken timestamp-version candidate)
and j-interop 2.0.4 (legacy major) pinned
Co-Authored-By: Claude <noreply@anthropic.com>
- include dc3-db in the make deploy artifact set alongside common/mq/tsdb
- sample DC3_DB_TYPE/DC3_TSDB_TYPE and external-store ports in .env.example
- expose mysql/mariadb/tdengine/influxdb/iotdb/jaeger in the compose stacks
- update AGENTS.md module map and module-ownership guidance
- add the missing AGPL header to the oracle driver service
A comment-health audit driven by an AST scanner (regex scanners kept
false-positiving on annotation-separated javadoc; the AST pass with
constructor and @Override-implementation exemptions is what produced a
trustworthy worklist) ended with a much smaller true gap than the raw
numbers suggested: class-level javadoc is already at 100% repository-wide.
What actually gets filled here:
- AnalyticsModel: all 30 nested records of the S19 analytics facet get
maintainer-voice javadoc (the @Schema descriptions serve the API side;
these serve code readers).
- The whole entity/ext family (29 files, 47 nested classes): every
Content/Ui/Validation/Security/AppliesTo/Template/Dedup/... schema
class states what it actually holds — read from the fields, not
templated.
- Adapter families: the @Bean methods of all six MQ adapters, all four
TSDB adapters and the three DB dialect adapters get one-line
maintainer docs (what binds to what, what is overridable).
- Nested support types across data/agentic/constant/public/facade:
NotifyBindKey, CacheTuning, Credential, dashboard VOs' Item/BucketVO,
ExpireListener (plus its null-doc placeholder javadoc replaced with a
real contract), agentic chat/stream VOs' choice/delta/usage shapes,
tool-context records, RequestHeader envelopes, FleetSummary,
visualization Type/Scale codes.
- PointValueSampleConverter's boundary methods now state the port-side
contract (quality default injection point, batch order preservation).
Comment drift fixed: the class javadoc of the can/mqtt/opc-da driver
skeletons claimed "see TODO markers in method bodies" — those markers
do not exist; the claims are corrected to plain work-in-progress notes.
The genuine TODOs (zigbee API verification, lwm2m lookup, ethernet-ip
CIP framing, CAN JNI) stay: they mark real unimplemented behavior.
Vendored-code boundary: the opc-da module carries a ported
org.openscada library (46 files, package org.openscada.*). Its trivial
accessors stay bare on purpose — filler comments on get/set pairs are
exactly the kind of noise this pass exists to remove — but the
non-obvious JIStruct wire-decoder methods (getStruct/fromStruct
FILETIME + three DO wrappers) now document the COM bridge shape.
Gates: full-repo compile green; data/model/constant/agentic/public
test suites green.
Apply queryTimeout as a statement timeout instead of a connection timeout, validate point queries against the point read/write flag, close all connection pools on driver metadata events, and remove the unused DriverSenderService dependency. Rename the module unit test so surefire executes it (26 tests) instead of excluding it via the Abstract* pattern.
Use PostgreSQL leases and fencing for distributed ownership, require a durable SQLite outbox before RabbitMQ publication, and make Data Center ingestion transactional and idempotent.
BREAKING CHANGE: drivers require mandatory durable outbox configuration and use lease-aware ownership and telemetry contracts.
Prose rewrapping and table reflow from a project-wide markdown pass;
no content changes. Also reverts two formatter mistakes: restores
MD5(password) in dc3-web/AGENTS.md and drops spurious spaces after
CJK punctuation in README.zh.md / README.ja.md.
Covers root guides (AGENTS/CONTRIBUTING/SECURITY/README.*), module
READMEs across dc3-api/center/common/driver/e2e/gateway, the nginx
guide, dc3/doc/{README,TITLE}.md, and dc3-web docs.
* style(backend): reformat and rearrange java/xml sources
Apply code cleanup across dc3-common and dc3-driver: whitespace and
indent normalization, import sorting, member rearrangement, and javadoc
normalization. No semantic changes; compilation verified.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* style(docs): reformat vitepress vue diagram components
Expand compact svg templates and normalize formatting across diagram
components, the seo module, and the theme stylesheet. No behavior
changes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* style(docs): reformat markdown pages
Normalize markdown formatting. Restore the <script setup> component
imports that an earlier unused-import pass had wrongly stripped; every
<Diagram> tag now resolves to a backing import again.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* style: reformat point view and trim pom whitespace
Normalize whitespace in the point view and drop trailing whitespace in
pom.xml. No behavior changes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix(security): sanitize agentic assistant HTML with DOMPurify (XSS)
RenderedAssistantMessage rendered model output via v-html after a
hand-rolled regex sanitizer that CodeQL flagged 5 ways: bad-tag-filter,
incomplete-multi-character-sanitization (on* attributes, javascript:),
incomplete-url-scheme-check (data:/vbscript:). Replace with DOMPurify,
which covers all these plus mutation XSS. Fixes CodeQL #2146-2150.
* fix(security): harden log-injection + CAN command injection
log-injection (7): pass user-derived log args (conversationId, model,
candidate/fallback) through LogSanitizer.sanitize in AgenticChatServiceImpl,
ChatClientFactory, AgenticChatRequestPreparer — strips CR/LF that could
forge log lines.
relative-path-command / command injection (2, CanDriver): executeCommand
runs `sh -c` with a command built from driver config (interfaceName) and
request data (canId/frame), so add a CAN_COMMAND_PATTERN whitelist
(^[A-Za-z0-9 _#,.=%/-]+$) rejecting shell metacharacters, and validate
interfaceName against ^[A-Za-z0-9_]+$ at all 3 entry points. Fixes
CodeQL #2173,#2172,#2120,#1514,#1513,#1022,#1017,#1016,#1014.
Verified: mvn compile agentic+can clean.
M6 relocated CoapExchange from core.server.resources to core (verified
via compile). dc3-driver-coap uses only the core CoAP API
(CoapClient/Server/Endpoint/Resource/Configuration) and avoids the
DTLS/observe/MessageObserver areas where M3→M6 broke, so this single
import is the whole adaptation. Supersedes dependabot #81.
Gains: M4-M6 bugfixes (deferred CID records, CON notify reliability,
anonymous cipher-suite), Java 21 virtual-thread support, RFC 7252
compliance. 4.0.0 GA has no timeline; no reason to stall on M3.
28 driver application.yml add dc3.driver.buffer; Dockerfile each stage adds dc3/data dir and VOLUME; docker-compose main/dev add driver_data named volume
Add LogSanitizer and apply it to agentic conversationId/model and the listening-virtual netty deviceName so they are not emitted verbatim in log output.
Co-Authored-By: Claude <noreply@anthropic.com>
Wrap unchecked Integer/Long/Byte.parse* calls in topic/dashboard/oauth/facade and the BACnet-IP, Ethernet-IP, FINS, SNMP drivers plus the agentic action payload, so malformed values fall back to a safe default instead of aborting.
Co-Authored-By: Claude <noreply@anthropic.com>
Remove configuration duplicated verbatim by the auto-activated shared profile bases: the dc3-center-manager gRPC channel in several drivers, the management.* block in center/gateway services, the gateway swagger-ui.path, duplicate logging sub-packages, and dead dc3.driver.mqtt config in dc3-center-data (no dc3-common-mqtt dependency). spring.env/spring.group are kept (consumed by RabbitmqEnvironmentConfig/WebFluxSecurityConfig/HmacAuthConfig). Effective configuration unchanged; validated via YAML parse + Maven process-resources.
Co-Authored-By: Claude <noreply@anthropic.com>
The server was constructed with only CoapConfig.COAP_PORT set, so
Californium created a default endpoint bound to 0.0.0.0 (all
interfaces) — coapProperties.serverHost was never applied, yet the
startup log printed it as the listen host. Setting serverHost to a
specific interface silently failed to restrict binding. Add an explicit
CoapEndpoint bound to InetSocketAddress(serverHost, serverPort) so the
property takes effect and the log is accurate.
Verified: dc3-driver-coap compiles.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two runtime bugs in the FINS driver:
1. read() hardcoded a 1-word (2-byte) memory-read request regardless of
dataType, so INT32/UINT32/FLOAT decodes (which need 4 bytes) always
threw BufferUnderflowException — 32-bit points could never be read.
Derive the word count from dataType (2 words for 32-bit types).
2. encodeWriteData grouped FLOAT with INT32/UINT32, doing
Integer.parseInt + putInt. Writing "3.14" threw NumberFormatException
and "3" was written as int bits (read back as ~4.2E-45 via getFloat).
Give FLOAT its own branch using Float.parseFloat + putFloat.
Relaxed encodeWriteData/decodeValue/wordCount to package-private and
added round-trip tests (FLOAT, INT32) plus wordCount coverage.
Verified: dc3-driver-fins 7 tests pass.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Align @param tag indentation in AgenticChatResponseCodec, GrpcFacadeSupport, PlcS7DriverCustomServiceImpl
- Align markdown table columns in docs/en and docs/zh architecture, technology-stack, operation, quickstart
- Reformat vitepress config group items for readability
- PlcS7DriverCustomServiceImpl: document getS7PLC/buildVariable/
readByType/writeByType/invalidateConnection/closeConnection
- MelsecDriverCustomServiceImpl: document the same six helpers
(McPLC variant); both drivers shared the undocumented helper pattern
while modbus-tcp/mqtt/opc-ua already documented theirs
Fix @since 2026.6.2 -> @since 2026.5.22 on 40 files across 17 protocol
drivers (serial, dlms, fins, mysql, ethernet-ip, zigbee, bacnet-ip,
snmp, ble, can, oracle, postgresql, iec104, lwm2m, tcp-udp, http,
sqlserver). The @since value was later than @version 2026.5.22, which
is impossible — a class cannot exist in 5.22 yet be introduced in 6.2.
Replace unused catch exception parameter names ('e', 'ex', etc.) with
the conventional 'ignored' identifier to suppress IDE warnings across
the codebase. This is a purely mechanical rename — no behavioral change.
Affected modules: enums (40+), drivers (12+), common-data, common-driver,
common-manager, common-auth, common-public, common-agentic, common-web,
common-resource-registrar, and all driver implementations.
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(driver-mqtt): report real broker connection state in driver health
* fix(driver-opc-ua): expose certificate-degraded marker in health description
* fix(driver-opc-ua): use x509 identity provider when certificate is configured
* fix(driver-opc-ua): add connection backoff to prevent connect storms on unreachable devices