122 Commits
Author SHA1 Message Date
pnoker 51edc7c198 refactor(common): rename resource registrar module 2026-09-01 23:42:00 +08:00
pnoker eae86b58fc refactor(storage)!: unify platform persistence on reactive postgresql
- 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.
2026-09-01 22:03:16 +08:00
pnokerandClaude fb97274691 build(deps): bump spring boot to 4.1.1 and refresh dependency stack
- 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>
2026-08-27 07:47:23 +08:00
pnoker 5a89b39ec1 refactor(build): move the relational core into the db family as dc3-db-core
dc3-common-jdbc was the family's core in disguise — MyBatis-Plus wiring,
the tenant-line handler, the databaseIdProvider, the jdbc profile. It now
lives as dc3-db/dc3-db-core, matching the dc3-mq-core / dc3-tsdb-core
shape: one aggregator, port first, adapters after, tck last. Artifact
renamed, packages deliberately untouched (same convention as the mq
family move); twelve poms rewired, the family aggregator puts core
first, and the db-tck now depends on the core explicitly instead of
riding transitives.

dc3-common-sql stays where it is on purpose: it is not platform dialect
plumbing but the base class of the four JDBC *device drivers*
(mysql/oracle/postgresql/sqlserver drivers that connect to external
databases being collected from) and depends on the driver SDK — under
dc3-db it would claim a meaning it does not have.

Gates: db-tck 24/24 (postgres + mysql + mariadb), data 274/274,
full-repo compile green.
2026-08-24 20:19:06 +08:00
pnoker c6509762a6 refactor(db): split relational infra into a neutral jdbc module and a postgres dialect family
R1 of docs/design/storage-abstraction.md §3 — zero behavior change:

Portable SQL rewrites (verified against a live PostgreSQL before landing):
- COUNT(*) FILTER (WHERE) x3 -> COALESCE(SUM(CASE WHEN ... THEN 1 ELSE 0
  END), 0); the COALESCE keeps the empty-set result at 0 where bare SUM
  would return NULL.
- dailyTrend's generate_series + date_trunc calendar spine -> a
  RECURSIVE CTE day ladder (CAST(day + INTERVAL '1' DAY AS DATE) keeps
  the column type stable on both engines — the bare date+interval form
  widens to timestamp on PostgreSQL and fails the recursive term's type
  check, caught live); day rendering via CONCAT instead of ::text.
- OAuthMcpMapper: '{} '::JSON literals -> '{}' (unknown literals coerce
  to the JSON column on both engines), NULL::BIGINT -> NULL in the
  UNION arm, #{riskLevel}::text parameter casts dropped (the text column
  compares untyped parameters fine on both).
- The reserved-word alias AS key (a MySQL landmine hiding inside three
  otherwise-portable statements) renamed to bucket_key / bucketKey
  across both Dashboard mappers and BucketRow.

Module split: dc3-common-postgres -> dc3-common-jdbc (MyBatis-Plus
wiring, tenant-line handler, generator utils, the new dialect-neutral
jdbc profile carrying the shared mybatis-plus/hikari plumbing) + the
top-level dc3-db family's dc3-db-postgres (driver, timestamptz type
handler, postgres profile delta, and the pagination DbType bean the
neutral config now injects — defaulting to PostgreSQL so a bare
jdbc-only classpath behaves exactly as before). Packages deliberately
unchanged, mirroring the mq/tsdb family moves; all nine dependent poms
rewired; make deploy publishes the dc3-db family.

The jdbc module's interceptor integration test now pins an explicit
embedded H2 datasource — the module carries no driver on its main
classpath, so context inference would fail without it.

Gates: data/auth/manager/jdbc/db-postgres unit suites green (274 in
data), full-repo compile green, e2e 26/26.
2026-08-24 16:44:47 +08:00
pnoker edadfa0a06 feat(tsdb): rewire the data center onto the tsdb port and retire the repository module
Phase 1b of docs/design/tsdb-abstraction.md: every point-value read and
write now flows through the dc3-tsdb port, and dc3-common-repository is
deleted outright (no compat aliases).

Write path — new PointValueIngestService orchestration in dc3-common-data:
the stale-owner lease guard leaves the history INSERT's cross-schema join
and resolves the active owner per distinct device through the existing
DeviceFacade.getActiveOwner chain; a caffeine-backed ingest idempotency
window (dc3.data.ingest.*, marked only after both writes commit) absorbs
MQ redeliveries now that the message_id unique index is retired; the
batch lands via TsdbStore.append (natural series+time upsert, INGEST_ORDER
kept for the fenced dc3_point_latest upsert).

Read path — history via last(), page() resolves name/enable filters to
series keys through relational metadata (tenant-wide when unrestricted,
cursor offset emulation capped at 10k) with count() for totals; the alarm
window backend becomes TsdbWindowDataSource over aggregate()/history().

Dashboards — all nine data-side hypertable statements move to the S13
analytics facet (count/bucketedCount/countByDimension/latencyHistogram/
lastSeenPerSeries) plus the dc3_point_latest projection for latestStream;
the manager topology statement crosses into the data center via a new
ListSeriesVolumes RPC backed by the new S13-5 seriesCounts primitive (a
point shared by several devices needs per-series counts, which
single-dimension grouping cannot reconstruct); both cross-schema joins
are gone.

Port/adapter — seriesCounts added with a TCK case (23 total); series
filters compile to row-value IN lists chunked at 500 pairs; bootstrap
adds the quality column idempotently and retires uk_point_value_event so
existing deployments converge on the new upsert; the adapter binds the
application-provided tsdbDataSource bean (the history dynamic-datasource
entry) instead of the routing primary.

Timestamps — BO<->Instant conversion is pinned to
TimeConstant.DEFAULT_ZONEID (the platform canonical zone the latest
projection type handler already writes with); the design note's "lock
UTC" is amended accordingly, together with the lease-guard and S13-5
deviations recorded in §6.2.

Seed/deploy — 05-iot-dc3-history.sql gains the quality column and swaps
the unique index; compose carries DC3_TSDB_TYPE; make deploy publishes
dc3-tsdb.

Also fixed along the way: root pom never managed dc3-mq-core (latent,
masked by full-reactor builds); PointValueMapper ran unrouted on the
master datasource (now @DS("history")); latestStream name enrichment
looked up a Long-keyed map with String keys.

Gates: tsdb TCK 23/23, dc3-common-data 262/262, e2e 26/26 including the
unmodified PostgresHypertableIT; full reactor green except dc3-mq-tck's
kafka/pulsar container-startup flake, reproduced identically twice and
unrelated to this change.
2026-08-20 21:58:01 +08:00
pnoker d003291f81 refactor(build): extract the mq family into a top-level dc3-mq aggregator
The broker-selection family (port + six certified adapters + tck) is a
deployment selection, not shared plumbing, so it moves out of dc3-common
into a top-level dc3-mq aggregator beside dc3-api — the same standing as
the gRPC contract layer, and a template for future pluggable families
(storage is next on the design board).

- dc3-common-mq -> dc3-mq/dc3-mq-core (port: API + core runtime)
- dc3-common-mq-{rabbitmq,kafka,rocketmq,pulsar,activemq,mqtt,tck} ->
  dc3-mq/dc3-mq-{...}; no compatibility aliases — every coordinate is
  renamed everywhere in one commit (business poms, coverage, root
  dependency management)
- dc3-common sheds eight modules back to plain shared plumbing; the
  device-access dc3-common-mqtt stays by design (protocol stack, not a
  broker selection)
- Java packages deliberately stay io.github.pnoker.common.mq.* — the
  facade modules set the precedent that packages do not track module
  homes, keeping this a pom-only, zero-source refactor
- make deploy now publishes dc3-api + dc3-common + dc3-mq (third-party
  driver authors compile against the port transitively)
- docs/mq-brokers.md and the design's module layout follow the new home

Verified: full-repo test-compile green; constant/data/driver/manager
unit suites unchanged and green (255/144/291); the rabbitmq contract
suite passes 12/12 from the new coordinates against a live broker,
proving adapter wiring survived the move.
2026-08-20 12:23:09 +08:00
pnoker cc655699fd feat(mq): add pulsar adapter, completing broker coverage
Phase 3 (4/4) and the final piece of the mq abstraction: every broker
named in the design is now a TCK-certified selection behind
dc3.mq.type. Pulsar suite 11 pass + 1 documented skip on the first run.

- topics map to persistent://public/default/dc3-<topic>, logical dead
  topics to dc3-<topic>-dlq; LOAD_BALANCE rides a durable shared
  subscription named after the consumer group (competing consumers,
  retained while offline), BROADCAST rides an exclusive per-instance
  subscription
- pulsar subscriptions start at the latest position natively, matching
  the rabbit fresh-queue / kafka latest semantics with no seeding
- acknowledge(List<MessageId>) commits deliveries, negativeAcknowledge
  requeues; reject(false) republishes to the -dlq topic and commits;
  poison and exhausted batches dead-letter through the shared
  synchronous bounded-retry semantics
- sends complete with the broker-issued message id (publisher
  confirmation); batchReceive is the native batch (capability true);
  arbitrary delays ride the port fallback like the other adapters
- tck harness against apachepulsar/pulsar standalone, or TCK_PULSAR_URL
  for an externally managed broker
2026-08-20 10:56:04 +08:00
pnoker fb703f5b64 feat(mq): certify the rocketmq adapter on the contract suite
Phase 3 (3/4): RocketMQ adapter (classic client) for
dc3.mq.type=rocketmq, TCK 11 pass + 1 documented skip against a live
nameserver/broker pair.

The 5.x classic client has two behaviors that had blocked certification,
both now handled in the adapter:

- brand-new consumer groups replay the topic backlog regardless of
  consumeFromWhere (LAST and TIMESTAMP both ignored), so fresh groups
  are seeded explicitly: a short-lived pull consumer sets every queue
  without a committed offset to the current max offset before the push
  consumer starts, matching the rabbit fresh-queue / kafka latest
  semantics; groups with a real offset trail are untouched
- subscribing to a topic that was never published to waits out the 30s
  route refresh, so subscribe-time seeding also warms up missing topics
  with a publish (the warm-up lands before the seeded offset, invisible
  to every fresh group)

Further fixes surfaced by the suite: dead-letter republishes only the
standard envelope headers (RocketMQ system properties like
CONSUME_START_TIME are rejected on re-publish), and requeues request the
1s delay level so bounded retry exhaustion dead-letters within the
contract window instead of the 10s default.

Topics map to dc3-<topic> (no dots), dead letters to dc3-<topic>-dlq;
LOAD_BALANCE rides CLUSTERING consumer groups, BROADCASTING fans out per
instance; sync sends are the publisher confirmation; arbitrary delays go
through the port fallback (delay levels would quantize). The tck harness
is opt-in via TCK_ROCKETMQ_NAMESRV (testcontainers cannot manage the
nameserver/broker pair); a fresh-group isolation probe rides along in
the adapter module, also opt-in.
2026-08-19 22:42:00 +08:00
pnoker 0250f9edea feat(mq): add mqtt 5 adapter passing the contract suite
Phase 3 (2/4): MQTT 5 adapter (hivemq client) for dc3.mq.type=mqtt,
working against any MQTT 5 broker with shared subscriptions (EMQX,
HiveMQ, NanoMQ, VerneMQ). TCK 10 pass + 2 documented skips.

- topics map to dc3/<topic> (slash style), logical dead topics to
  dc3/<topic>/dlq; LOAD_BALANCE rides $share/<group> shared
  subscriptions, BROADCAST rides a plain filter, and every subscription
  gets its own client session so broadcast instances are independent
- QoS 1 with manual acknowledgements: ack acknowledges the publish,
  PUBACK doubles as the publisher confirmation (capability true)
- MQTT has no server nack: reject(true) is approximated by bounded
  client-side redelivery, reject(false) republishes to the /dlq topic
  and acknowledges; poison and exhausted messages dead-letter
- delays go through the port fallback and batches are synthesized
  (capabilities false)
- the no-consumer durability case is disabled for this adapter with the
  design §13.8 reference: MQTT 5 leaves retention for an offline shared
  subscription to the broker (HiveMQ CE drops; EMQX-class brokers may
  retain) — the capability matrix documents the variance
- tck harness against hivemq-ce, or TCK_MQTT_HOST/TCK_MQTT_PORT for an
  externally managed broker
2026-08-19 21:37:55 +08:00
pnoker 65aa6d5956 feat(mq): add activemq adapter passing the contract suite
Phase 3 (1/4): ActiveMQ (Artemis / Classic, JMS 2.0) adapter for
dc3.mq.type=activemq, TCK 11 pass + 1 documented skip.

- live topics map to JMS topics: LOAD_BALANCE rides a shared durable
  subscription named after the consumer group (competing consumers share
  it, offline messages retained), BROADCAST rides a plain per-instance
  consumer — one publish fans out to every subscription like an exchange
- dead-letter destinations are queues; reject(false) republishes to
  dc3.<topic>.dlq and acknowledges, reject(true) recovers the session
- delays use JMS scheduled delivery natively (capability true); batches
  are synthesized by draining the consumer with the shared synchronous
  bounded-retry semantics; exhaustion dead-letters instead of dropping
- JMS property names must be java identifiers, so the dashed standard
  headers ride underscored and are restored on read
- best-effort publisher confirmation (capability false): the synchronous
  persistent send returning is the reported signal
- tck harness against apache/activemq-artemis, or TCK_ARTEMIS_URL for an
  externally managed broker; subscriptionExpiry documented false
2026-08-19 21:31:04 +08:00
pnoker b8aee2cf69 feat(mq): add kafka adapter and broker-neutral contract suite
Phase 2 of the mq abstraction design: the acceptance bar (TCK) plus the
kafka adapter, both passing the full contract suite against live brokers.

dc3-common-mq-tck (contract suite, reusable by community adapters):
- abstract 12-case suite covering round-trip envelope fidelity, load
  balance exactly-once across instances, broadcast fan-out, delay via the
  port fallback, reject-to-dead-letter, reject-with-requeue redelivery,
  sendAsync confirmation, 100-message burst, batch ack committing the
  whole batch, retry exhaustion dead-lettering instead of dropping,
  durability while no consumer runs, and per-instance subscription expiry
- rabbitmq and kafka harnesses on testcontainers 2.x, skipped gracefully
  without a container runtime; kafka harness also honors TCK_KAFKA_BOOTSTRAP
  for externally managed brokers (testcontainers 2.0.5 configures
  apache/kafka 3.9.0 with a nonroutable advertised listener on some runtimes)
- per-run unique consumer groups plus post-subscription settle keep runs
  isolated on log-based brokers with auto.offset.reset=latest

dc3-common-mq-kafka (adapter, dc3.mq.type=kafka):
- topics map to dc3.<topic>; logical dead topics map to dc3.<topic>.dlq so
  rejects and dead-letter subscriptions land on the same topic
- partition key becomes the record key (per-key ordering); LOAD_BALANCE
  rides consumer groups, BROADCAST uses per-instance group ids
- auto.offset.reset=latest mirrors the rabbit fresh-queue semantics: a new
  group only sees messages published after it joins
- batch delivery with synchronous bounded retry and backoff mirroring the
  rabbit stateless retry advice; exhaustion republishes the whole batch to
  the dead-letter topic and commits instead of dropping silently (spring's
  DefaultErrorHandler committed exhausted batches without publishing)
- non-poison failures on single deliveries nack for redelivery; poison
  messages are republished to the dead-letter topic and acknowledged

rabbit adapter adjustments surfaced by the suite: delayedMessage capability
is now false (only the intrinsic TTL+DLX topics delay server-side; arbitrary
delays go through the port fallback), POINT_VALUE_DEAD is subscribable for
dead-letter auditing, spec instanceTtl overrides the configured queue
expiry, subscriptions with a named group get a group-suffixed copy of the
platform-shared queue (blank group keeps the pre-port names), and shared
topology moved to a descriptor table

Verified: RabbitMQ 12/12 and Kafka 11+1-skipped against live brokers via
podman; constant/data/driver/manager unit suites unchanged and green.
2026-08-19 20:52:27 +08:00
pnoker 28efa5c8fc refactor(mq): migrate business modules onto the messaging port
Complete phase 1 of the mq abstraction design: business code compiles
against the broker-neutral port with zero amqp classes, and the legacy
dc3-common-rabbitmq module is deleted.

- dc3-common-driver: 8 sender methods plus the sqlite outbox now publish
  through MessageSender (outbox keeps durability; legacy physical routing
  keys in pending rows are normalized on republish); metadata/command/
  point-command receivers become @Dc3Listener subscriptions with
  placeholder-driven per-instance queues; DriverTopicConfig dissolved into
  adapter subscribe-time declarations
- dc3-common-data: command and point-command dispatch use sendConfirmed
  with the correlation-id header; state timeout, device scan tick, notify
  tasks and metadata events send through logical topics; all 13 receivers
  including the batch point-value consumer migrate to @Dc3Listener;
  DataTopicConfig, PointValueRabbitConfig and the duplicated batch
  properties class move into the port/adapter (same config keys)
- dc3-common-manager / facade-local-manager: metadata fan-out via the port
- dead-letter consumers read the correlation id from the standardized
  header the adapter mirrors onto the amqp property
- 14 test classes adapted to the new listener/sender shapes; module poms
  swap dc3-common-rabbitmq for dc3-common-mq + dc3-common-mq-rabbitmq

Verified: unit suites green for constant (291 incl. boundary guard),
data (165), driver (144), manager (255); full-repo main and test compile
green. Container-backed E2E (RabbitDeliveryIT) intentionally not run here.
2026-08-19 18:47:50 +08:00
pnoker f0c6e9bf25 feat(mq): add broker-neutral messaging port and rabbitmq adapter
Introduce the pluggable message broker layer from the mq abstraction
design. Existing rabbitmq deployments keep their topology byte-for-byte.

dc3-common-mq (port, zero broker dependencies):
- MqTopic logical destinations, JSON envelope with standardized headers
  (dc3-type, X-Request-Id via MDC/OpenTelemetry, correlation id)
- MessageSender send/sendAsync/sendConfirmed plus local-scheduler delay
  fallback for brokers without native delayed delivery
- @Dc3Listener annotation processor: resolves payload types from method
  signatures, resolves ${...} placeholders in keyPattern/group, restores
  the request id into the MDC around every invocation
- SubscriptionSpec (mode, profile, delivery, keyPattern, group) and
  BrokerCapabilities negotiation logged at startup

dc3-common-mq-rabbitmq (adapter, dc3.mq.type=rabbitmq, default):
- RabbitNames replicates the pre-port physical names exactly, including
  the historical tag inconsistency between routing-key families
- RabbitTopology declares exchanges/queues/bindings programmatically with
  identical TTL, dead-letter and binding-argument details; driver-side
  per-instance queues are declared on subscribe with lease-coupled x-expires
- one listener container per subscription: latency 2/8/10, throughput
  4/32/100, batch consumer replicated from the point-value factory
  (prefetch >= batchSize, batch-level bounded retry, exhaustion dead-letters)
- stamps legacy __TypeId__ for rolling upgrades and mirrors the correlation
  id onto the AMQP property for dead-letter consumers

Shared enums (MqTopic, SubscriptionMode, ConsumptionProfile, DeliveryMode,
OrderingGuarantee) live in dc3-common-constant per the module boundary
guard. The legacy dc3-common-rabbitmq module is retired in the next
commit; both coexist so this commit stays independently buildable.
2026-08-19 18:47:24 +08:00
pnoker 5730f7c137 feat: update pom version 2026-06-06 13:00:39 +08:00
pnoker b5ef7a8501 fix(pom): clean up dependency management and plugin configuration
- 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
2026-06-06 00:40:18 +08:00
pnoker 26f6e91a64 feat(driver): add 17 protocol drivers to extend IoT connectivity coverage
## 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
2026-06-02 09:54:13 +08:00
Vickey 918b3d5e8e feat: update pom version to 2026.5.22 2026-05-26 00:30:11 +08:00
pnoker 9007cbc22c style: apply consistent code formatting across all modules and docs 2026-05-22 00:24:22 +08:00
pnoker 5a3ab1440a test: improve backend test coverage governance 2026-05-19 18:19:12 +08:00
pnoker 7f5da1a0f8 chore: bump version to 2026.5.18 across all modules 2026-05-18 00:24:22 +08:00
pnoker 996518186a build: bump version to 2026.5.17
Update parent version and dc3.version from 2026.5.5 to 2026.5.17
across all Maven modules.
2026-05-17 19:01:44 +08:00
pnoker 019daf62ce feat: do someting test and code review 2026-05-16 00:56:04 +08:00
pnoker 9123b480f4 test(e2e): stabilize infrastructure harness 2026-05-14 21:29:08 +08:00
pnoker ade8579369 fix(test-infra): propagate test bom into dc3-common dependency management
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.
2026-05-13 13:17:55 +08:00
Vickey 36ffe2bb6f test(infra): introduce dc3-common-test module with shared fixtures
Bootstrap dc3-common-test, a new infrastructure-only Maven module under
dc3-common that ships:

- Reusable Testcontainers wrappers for the production-aligned
  timescale/timescaledb-ha:pg18 image, RabbitMQ with publisher confirms
  and Eclipse Mosquitto MQTT broker.
- JUnit 5 support beans: a fixed Clock configuration, an in-process gRPC
  extension, an Awaitility-backed Rabbit harness and JSON assertion
  helpers.
- Reusable contract base classes for domain enum index round-trips and
  for asserting that secret-bearing fields never leak through Lombok
  toString() output.
- A test profile (application-test.yml) and logback config aligned with
  the production RabbitMQ confirm/return semantics.

Module-specific fixtures that depend on business BO/VO/DO types are
deliberately deferred to their owning modules' src/test trees to avoid
introducing reverse dependencies into dc3-common-test.

This commit only adds the new module; no other module consumes it yet.
The test BOM and plugin wiring that exposes it as a test-scope artifact
to the rest of the tree lands in a follow-up commit.
2026-05-13 11:10:25 +08:00
pnoker e47299a327 chore: remove format and format-check targets from Makefile 2026-05-07 23:55:32 +08:00
pnoker eefe411bd7 chore(build): upgrade spring-javaformat to 0.0.47 and add Checkstyle integration
- Add maven-checkstyle-plugin with spring-javaformat-checkstyle rules
- Add custom checkstyle.xml excluding overly strict rules for existing codebase
- Exclude third-party driver code (serotonin, openscada, nodave) from checks
- Configure plugins in dc3-common and dc3-api POMs for full module coverage
- Add .springjavaformatconfig placeholder
2026-05-07 16:46:17 +08:00
pnoker dea8482001 feat(agentic): add AI agentic center with Spring AI tool-calling
Introduce dc3-common-agentic (skill registry, tool sets for auth/manager/data,
chat client) and dc3-center-agentic (deployable service). Register Spring AI BOM,
add gateway route /api/v3/agentic/**, and configure OpenAI env vars.
2026-05-07 00:09:38 +08:00
pnoker 95c40b2387 chore: bump version to 2026.5.5
Roll every pom, per-module README, Spring banner, and @version /
@since javadoc tag from 2026.4.30 to the new 2026.5.5 release line.
2026-05-05 00:56:09 +08:00
pnoker da5c02efd6 refactor: restructure facade module to aggregator pom, split local into auth/manager submodules
- 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
2026-05-01 00:48:50 +08:00
Vickey fb9ee53781 feat: auto-register center API endpoints to auth resource tables
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)
2026-04-30 21:40:45 +08:00
Vickey 200beeaa71 chore: update version to 2026.4.30 in multiple files 2026-04-30 16:06:30 +08:00
pnoker 7ed333d760 fix: remove Redis module and dependency from pom.xml 2026-04-29 16:00:16 +08:00
pnoker c5a9feeeb9 feat: add .env file for Docker Compose configuration and update usage instructions 2026-04-29 10:27:57 +08:00
pnoker fddf7bb60e feat(facade): introduce facade layer for cross-service calls
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.
2026-04-27 19:46:15 +08:00
pnoker ea17c86387 chore: update version to 2026.4.19 across all modules and adjust branch settings in codeql.yml 2026-04-19 13:45:21 +08:00
pnoker e38b5e6b64 refactor: optimize root, dc3-common and dc3-api pom.xml
- 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:git: protocol prefix
- Fix <inceptionYear> from range '2016-2022' to correct single year '2016'
2026-04-18 01:15:20 +08:00
pnoker e57793ec5f chore: bump version to 2026.4.18.3 and optimize pom.xml dependencies
- 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
2026-04-18 01:05:30 +08:00
Vickey 0e419bab05 feat: update pom 2025-11-11 13:22:24 +08:00
zzi666 73fe41091e refactor: standardize descriptions, comments, and documentation across POM files and Protobuf definitions 2025-10-24 20:07:28 +08:00
zzi666 989a931c2f fix: standardize comment language in POM files 2025-10-24 15:45:02 +08:00
Vickey a9e8d05631 feat: update version 2025-10-05 17:16:37 +08:00
Vickey 7302107c56 chore: bump all module versions to 2025.9.2 2025-09-11 17:02:24 +08:00
Vickey 2051d42847 refactor(common): remove hutool dependency and replace usages with native utilities 2025-09-11 14:57:02 +08:00
Vickey 8cc7365293 build: bump all module versions to 2025.6.6 and update compose image tags 2025-08-26 22:38:53 +08:00
Vickey 022bab4fbd chore: switch license declaration from Apache-2.0 to AGPL-3.0 across all poms 2025-08-26 22:16:35 +08:00
Vickey a39d2fb533 chore: migrate license headers from Apache 2.0 to AGPL-3.0 across all source files 2025-08-26 22:01:24 +08:00
Vickey f415207088 build: bump project version to 2025.6.5 across all modules 2025-07-15 14:58:51 +08:00
Vickey 31a6a275ed build: bump project version to 2025.6.4 across all modules 2025-07-15 12:01:43 +08:00