Add the first driver integration test: spins a real PostgreSQL container and
verifies the shared JDBC read path returns stored values and that the write
path binds the point value as a parameter — a SQL-injection payload is stored
verbatim and cannot drop the table, confirming the parameterised-write fix
end-to-end. Set the Failsafe classesDirectory so integration tests run against
the plain compiled classes instead of the Spring Boot repackaged fat jar.
Replace the unsafe (T) cast of PemReader.readPemObject() — which threw
ClassCastException at runtime — with explicit conversion: X.509 certs via
CertificateFactory and private keys (PKCS#1/PKCS#8, encrypted or plain) via
BouncyCastle's PEMParser. Add the bcpkix dependency and unit tests covering
the encrypted-key path used by MQTT TLS.
Make the REST API documentation actually reachable end-to-end:
- Upgrade springdoc to 3.0.3 (Spring Boot 4 / Spring Framework 7 compatible)
and pin swagger-core 2.2.47 to resolve the Spring AI conflict.
- Register SpringDocConfig and WebFluxSecurityConfig as @AutoConfiguration so
they load (they sit in io.github.pnoker.common.config, which centers do not
component-scan); add the global OpenAPI info + X-Auth security schemes.
- Add per-module GroupedOpenApi beans (auth/manager/data/agentic) and gateway
aggregation routes + swagger-ui.urls for a single federated Swagger UI.
- Fix the security chain: guard WebFluxSecurityConfig off the gateway, supply a
permissive default PermissionProvider, register the @perm bean, and correct
the token-path whitelist (base-path is stripped before the chain).
- Whitelist doc paths; disable docs in the production profile.
- Register swagger-ui webjar resources (default static mappings are disabled).
- Replace obsolete nexus-staging-maven-plugin with central-publishing-
maven-plugin in dc3-api and dc3-common
- Remove 20 redundant version declarations from dc3-coverage dependencies
- Fix snmp4j version from non-existent 3.8.3 to available 3.7.4
## Common Foundation
- dc3-common-sql: AbstractJdbcDriverCustomService base class with HikariCP
pool management and JDBC template methods
## Serial & General-Purpose (3)
- Serial: RS232/RS485/RS422 with configurable frame parsing (CRC16/XOR)
- HTTP: REST Client using Spring WebClient with JSON path extraction
- TCP/UDP Raw: generic socket driver with pluggable frame protocol
## Database Drivers (4)
- MySQL, PostgreSQL, Oracle (SID/ServiceName), SQL Server
## IoT & Wireless Protocols (3)
- LwM2M: Eclipse Leshan 2.0.0-M14 with CoAP server and device observation
- Zigbee: Z-Smart Systems 1.4.16.1 with Telegesis dongle support
- BLE: Sputnikdev Bluetooth Manager 1.5.3 with TinyB transport
## Building Automation & Smart Metering (2)
- BACnet IP: BACnet4J 6.0.1 with ReadProperty/WriteProperty support
- DLMS/COSEM: Gurux DLMS 4.0.79 for smart metering (TCP/Serial transport)
## Industrial & Power Protocols (4)
- IEC 104: OpenMUC j60870 1.7.2 for power telecontrol
- SNMP: SNMP4J 3.7.4 for network device monitoring
- EtherNet/IP: CIP Data Table Read/Write for Rockwell AB PLCs
- FINS: Omron PLC memory area read/write over TCP
## Automotive & Fieldbus (1)
- CAN Bus: SocketCAN interface with standard/extended frame support
## Build
- Register all 17 driver modules and dc3-common-sql in parent POMs
- Add version properties and dependencyManagement entries
feat: new driver modules
- dc3-driver-melsec: Mitsubishi Melsec MC (1E/3E/4E frame) driver via iot-communication
- dc3-driver-sl651: SL651-2014 hydrological telemetry server-side driver via iot-communication
- Bump iot-communication from 1.5.4 to 1.5.6 in dc3-driver-plcs7
- Relocate ias-releases repository from root pom.xml to dc3-driver/pom.xml
fix: code review fixes across driver implementations
- PlcS7PointVariable: only include bit offset in address when bit access and offset > 0
- OpcDaDriverCustomServiceImpl: disconnect server on device delete/update
- OpcUaDriverCustomServiceImpl: disconnect client on device delete/update
- ModbusTcpDriverCustomServiceImpl: remove duplicate FLOAT case in write value switch
refactor: eliminate magic numbers, consolidate statics, and normalize log formatting
- NettyServerHandler: replace magic numbers with named constants
- OpcUaDriverCustomServiceImpl: replace magic timeout numbers with named constants
- ModbusFactory: consolidate static block into private static final field
- VirtualDriverCustomServiceImpl: replace new Random() with ThreadLocalRandom
- KeyLoader: reorder fields so statics precede instance fields
- Normalize log format from string concat to {} placeholders across multiple drivers
- MqttDriverCustomServiceImpl: downgrade QoS fallback log warn→debug
- Remove unused imports
- Add IoT DC3 layered architecture diagram (SVG + HTML viewer)
with Application / Management / Data / Driver layers,
Security & Load and Platform & System sidebars,
Data→Driver connection flows, and color-coded sections
- Reposition README descriptions across all languages (en, zh, ja, vi)
and pom.xml to AI-ready narrative: "Connects devices, collects
data organized for AI, and orchestrates the closed loop"
- Add README.ai.md with Chinese multi-paragraph AI narrative
and closed-loop flowchart
- Optimize package.json metadata (name, license, scripts)
Bump spring-ai-bom in root and agentic module POMs. API is fully
compatible — no code changes required. Full project build and 89
agentic module tests pass.
Maven dependencyManagement does not flow across the iot-dc3 root reactor
into dc3-common because dc3-common inherits from the externally
published dc3-parent. As a result, dc3-common-test could not resolve
JUnit 5 / Testcontainers / Instancio dependencies and dc3-e2e could not
resolve dc3-common-test itself.
Mirror the relevant slice of test-toolchain version management into
dc3-common/pom.xml (junit-bom + testcontainers-bom imports plus pinned
versions for AssertJ, Awaitility, Instancio, REST-assured and WireMock)
and add the missing dc3-common-test version entry to the iot-dc3 root
dependencyManagement so the e2e module can import it.
Verified locally with mvn -B clean compile -pl dc3-common/dc3-common-test -am,
which now resolves all 9 source files and produces
dc3-common-test-2026.5.5.jar.
Introduce two reactor modules that exist purely to host repository-wide
test concerns:
- dc3-coverage (packaging=pom) runs jacoco:report-aggregate against all
contributing modules and applies a tree-wide jacoco:check rule. The
aggregator excludes generated sources, deployable Application classes,
POJO entity packages and the third-party modbus4j sero utilities so
the percentage stays anchored on real business logic. Coverage gates
start at 0% and tighten in later stages as more tests land.
- dc3-e2e (packaging=jar) reserves a place for the docker-compose driven
end-to-end suite delivered in stage S8. Unit and integration phases
are skipped by default and only the e2e profile turns them on.
Both modules are wired into the root reactor.
Centralise test toolchain wiring at the iot-dc3 root pom so child modules
do not need to repeat versions or plugin definitions:
- Import the JUnit 5 and Testcontainers BOMs and pin AssertJ, Awaitility,
Instancio, REST-assured and WireMock versions.
- Add Surefire 3.5.2 and Failsafe 3.5.2 plugin management with the
expected include patterns (*Test.java for unit, *IT.java for
integration) plus argLine wiring for the Jacoco agents.
- Add Jacoco 0.8.12 plugin management with both unit and integration
agent + report executions; integration coverage lands in jacoco-it.exec
while unit coverage stays in jacoco.exec.
- Surface skip.unit.tests and skip.integration.tests properties so CI and
Makefile targets can flip phases without rewriting plugin configuration.
The new plugins are enabled at this layer; subsequent commits add the
aggregator coverage module that reads both .exec files and the workflows
that exercise them.
Group dependencies in each module POM using a standard category order:
Spring Boot → Spring Cloud → gRPC → Data Access → Messaging → IoT → AI
→ Serialization → Utility → Security → Observability → DC3 API → DC3 Common
DC3 Common dependencies sorted alphabetically within their group.
- Move dc3-common-facade-api, dc3-common-facade-grpc, dc3-common-facade-local
under new dc3-common-facade aggregator pom
- Split dc3-common-facade-local into dc3-common-facade-local-auth and
dc3-common-facade-local-manager for cleaner dependency scoping
- Update root pom.xml and dc3-common/pom.xml dependency management
- Update dc3-center-auth to use dc3-common-facade-local-auth
- Update dc3-center-single facade-local dependency type to pom
Adds a startup-time registrar that scans the local WebFlux handler mappings
of each center service and reconciles the discovered endpoints against
dc3_api and dc3_resource (insert-if-missing, update-if-drifted, soft-delete-
if-orphaned), so the permission model is no longer hand-maintained.
Wiring:
- dc3-common-resource-registrar (new module): scanner, diff runner, Spring
Boot AutoConfiguration. Activates on ApplicationReadyEvent.
- dc3-common-facade-api: ResourceRegistryFacade + BOs define a transport-
neutral sync contract.
- dc3-common-facade-local / dc3-common-facade-grpc: two implementations
selected via dc3.facade.mode. center-auth/single use local; manager/data
call auth via gRPC.
- dc3-common-auth: biz-side ResourceRegistrySyncService performs the three-
way diff inside a transaction guarded by pg_advisory_xact_lock(hashtext
(serviceName)); exposes ResourceRegistryApi gRPC server.
- dc3-api-auth: new resource_registry.proto contract.
- ApiDO/BO/VO/Query gain a serviceName field so each service's endpoints
can be located with a single indexed lookup.
Deployment-visible changes:
- api_code format is the human-readable serviceName:METHOD:/path
- dc3_resource.resource_code format is api:serviceName:METHOD:/path
(prefixed namespace reserved for future resource types)
- center-auth application.yml sets dc3.facade.mode=local
- 4 center pom.xml files pull in the registrar (auth also gets facade-local)
Adds three new modules that let business code call center services
through protocol-neutral interfaces instead of @GrpcClient stubs:
- dc3-common-facade-api: Device/Driver/Point + Tenant/User/UserLogin/Token
facade interfaces plus facade-owned BO/Query/Page types
- dc3-common-facade-local: in-process implementations backed by the
auth/manager services; zero serialization cost in single deployments
- dc3-common-facade-grpc: gRPC implementations holding BlockingStubs;
default mode for distributed deployments
Implementation selection is driven by dc3.facade.mode={local|grpc} via
@ConditionalOnProperty, with grpc as the matchIfMissing default. Wire-up
for dc3-center-single (dc3.facade.mode=local + facade-local dependency)
is included so the single-deployment mode is runnable out of the box.
- Consolidate 19+ individual DC3 module version properties into single <dc3.version>
- Remove redundant <scope>compile</scope> from DC3 Api dependencyManagement entries
- Reorder elements: modules before properties, profiles after dependencyManagement
- Fix <scm> connection/developerConnection to use scm protocol prefix
- Fix <inceptionYear> from range '2016-2022' to correct single year '2016'
- Bump all module versions from 2025.11.1 to 2026.4.18.3
- Remove orphaned dc3-common-influx dependency and property from root pom.xml
- Standardize dependency comment style in dc3-common/pom.xml
- Merge gRPC dependency groups into single section in dc3-common-api
- Restructure Spring Integration MQTT and Eclipse Paho groups in dc3-common-mqtt
- Fix incorrect comment 'DC3 Common Exception' to 'DC3 Common Related' in dc3-common-postgres
- Add missing blank line before </dependencies> in dc3-common-driver
- Remove stray blank line in root pom.xml dependencyManagement