Commit Graph

312 Commits

Author SHA1 Message Date
Eduardo Rios
50578fdba8 SIENTIAPDE-1974: feat(read): slot v2 reads via SubscriptionEngine, OPC cert from MinIO
Swaps the legacy OpcManager read path for the gateway's SubscriptionEngine over
the shared OpcConnectionPool. The OPC client certificate now always comes from
MinIO + Mongo (CertProvider, Basic256Sha256) — no more certs/ shipped in the
Gitea repository, so a new version branch no longer breaks the reads.

- io/slots.py: parse_slot accepts slot v2 (names[]) and converts the legacy
  v1 (tag_name + topics; cert_path => use_security, path dropped), so gateway
  and Orchestrator can be deployed in any order.
- managers/server_reader.py: new per-server reader with the OpcManager
  interface the IngestorManager already drives (connect, create_subscription,
  subscribe, unsubscribe, check_cycles, check_opc_listenning, shutdown).
- IngestorManager owns the read path: lazy-MinIO CertProvider, the pool and a
  read DataSink, built without touching the network. Slots from Redis are
  normalized on lease and refresh; a malformed slot is notified and the last
  good config is kept.
- GatewayRuntime borrows the pool (writes/gRPC) instead of building it, and no
  longer closes it on stop: a Postgres/NATS failure can't stop the reads.
- pool: pin/unpin per active subscription so release_idle never evicts a
  subscribed connection; public evict() for lost servers / changed config.
- SubscriptionEngine pins on subscribe, unpins on unsubscribe, and drops a
  subscription locally even when the server-side delete fails.
- DataSink: model_id only written when the name has one, keeping v1 documents
  identical to the legacy ones.
- config: CERT_BUCKET default is the legacy streamlit-connectors bucket (D7).
- Removes OpcManager, its tests and scripts/generate-and-push-opc-cert.sh;
  README/CLAUDE.md document the MinIO certificate and the slot v2 format.

Tests: 218 unit tests pass; ruff check/format clean. Local end-to-end against
an asyncua server: v1 slot with two topics -> one doc per collection, legacy
doc shape, idle sweep keeps the subscription, lost-server shutdown and
re-initialization work.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 13:27:18 -03:00
github-actions[bot]
4c85a9c5c2 chore: bump version to 2.0.0-rc3 2026-10-02 18:53:11 +00:00
966bb697b7 Merge pull request #38 from Aignosi/rc/ingestor2
SIENTIAPDE-1973: OPC Gateway — RC2 (GatewayRuntime wiring)
2026-10-02 15:52:43 -03:00
Eduardo Rios
7c02db7345 Merge branch 'release/SIENTIAPDE-1973' into rc/ingestor2
Brings the dependency fix from #39 (grpcio-tools moved to
requirements-dev.txt, protobuf>=7.35 added) and the 2.0.0-rc2 version.

Conflict in requirements-dev.txt resolved keeping both sides:
python-dotenv (rc/ingestor2) and grpcio-tools (release). Also restores
the missing newline that had glued python-dotenv onto the ipdb comment
line, so pip was not installing it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 15:39:53 -03:00
github-actions[bot]
9b91d195f6 chore: bump version to 2.0.0-rc2 2026-10-02 16:33:34 +00:00
Eduardo Rios
5c1f5b5747 Merge pull request #39 from Aignosi/rc/ingestor-deps
SIENTIAPDE-1973: fix(deps) — requirements instaláveis pelo índice do cluster
2026-10-02 13:33:07 -03:00
Eduardo Rios
2349912efb SIENTIAPDE-1973: fix(deps): make the gateway requirements installable from the cluster index
Workers install only from the cluster package index (install-entrypoint.sh:
pip install --index-url $PYPI_SERVER). The 2.0.0-rc1 deploy never became Ready
because two new requirements are not mirrored there:

- grpcio-tools: only needed to regenerate ingestor/proto/*_pb2*.py, which are
  committed. Moved to requirements-dev.txt (nothing imports grpc_tools).
- nats-py: needed at runtime; mirrored by library-distribution-controller#92.

Also declares protobuf>=7.35 explicitly: the committed stubs were generated with
protobuf 7.35.0 and validate the runtime version on import; until now it only
arrived transitively. The mirror carries 7.36.x.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 13:31:00 -03:00
ci-dependencies-fetcher[bot]
963b437937 Revert "chore: bump version to 2.0.0-rc1"
This reverts commit d7773d9e77.
2026-10-01 15:08:35 +00:00
Eduardo Rios
2f108ecbad Merge remote-tracking branch 'origin/release/SIENTIAPDE-1973' into rc/ingestor2
Merge feito para que a branch rc/ingestor2 passe a enxergar o rc 2
corretamente
2026-10-01 12:03:40 -03:00
github-actions[bot]
d7773d9e77 chore: bump version to 2.0.0-rc1 2026-10-01 15:02:31 +00:00
a083099e2d Merge pull request #37 from Aignosi/release-rc/ingestor1
SIENTIAPDE-1973: OPC Gateway — RC1 (write via NATS, active read, gRPC)
2026-10-01 12:02:00 -03:00
PedroHMCosme
e84b73631c Merge branch 'feature/SIENTIAPDE-1972-gateway-write-read' into feature/SIENTIAPDE-1972-gateway-wiring 2026-09-22 16:57:37 -03:00
PedroHMCosme
ff9339d408 fix(gateway): address SonarQube PR-mode findings on F2/F3 code
- data_sink.py: _IDENTIFIER_RE uses \w+/re.ASCII instead of the
  equivalent-but-verbose [A-Za-z0-9_]+ character class (verified same
  match behavior). NOSONAR on update_write_status's 'async with no
  await inside' - deliberate, per the ponytail comment already in the
  method body (uniform async interface across DataSink, no async pg driver).
- test_grpc_server.py: move make_request() out of the pytest.raises
  block so exactly one call can raise the expected exception.
- sonar-project.properties: exclude ingestor/proto/ (generated grpc
  code) from analysis - its ReadTag/etc. names are dictated by
  grpcio-tools, not a style choice, and renaming them breaks the wire.
2026-09-22 16:57:29 -03:00
PedroHMCosme
5daabc341a fix(gateway): suppress bandit B108 false positive on cert_cache_dir default
'/tmp/opc-certs' is a spec'd, overridable-via-env default (already
noqa'd for ruff's S108); bandit needs its own '# nosec B108' since it
runs as a separate CI step and doesn't read ruff's noqa comments.
2026-09-22 16:01:54 -03:00
PedroHMCosme
49ae26c621 Merge branch 'feature/SIENTIAPDE-1972-gateway-write-read' into feature/SIENTIAPDE-1972-gateway-wiring 2026-09-22 15:59:46 -03:00
PedroHMCosme
54408d6160 fix(gateway): suppress bandit B608 false positive in update_write_status
schema/table are allowlist-validated via _validate_identifier() before
interpolation (see docstring above), not a real SQL injection vector.
The existing '# noqa: S608' only silences ruff; bandit runs as its own
CI step and needs its own '# nosec B608' suppression syntax.
2026-09-22 15:59:36 -03:00
PedroHMCosme
fefc69bc4f Merge branch 'feature/SIENTIAPDE-1972-gateway-write-read' into feature/SIENTIAPDE-1972-gateway-wiring 2026-09-22 12:03:57 -03:00
PedroHMCosme
c0fd5c1b50 Merge branch 'feature/SIENTIAPDE-1972-gateway-foundations' into feature/SIENTIAPDE-1972-gateway-write-read 2026-09-22 12:03:29 -03:00
PedroHMCosme
e76df05e7a fix(gateway): suppress SonarQube S7504 false positive in close_all
list() here isn't redundant: _evict() pops from self._connections, so
iterating the dict directly would raise 'changed size during iteration'.
NOSONAR + comment explaining why, per Sonar's own suppression convention
already used in ingestor/app.py.
2026-09-22 12:03:21 -03:00
PedroHMCosme
673b13cc6e fix(gateway): adapt DataValue construction to asyncua 2.x
main's requirements.txt unpins asyncua (PR #30), so CI installs 2.0.1,
where DataValue's field was renamed StatusCode_ -> StatusCode. The old
kwarg made every OPC write raise TypeError at runtime - masked locally
by a stale asyncua 1.0.6 in the dev conda env. Also uses ua.DateTime
(a datetime subclass) and ua.UInt32 to satisfy the new stricter types,
with no behavior change (verified via binary encode/decode round-trip).
2026-09-22 12:02:29 -03:00
PedroHMCosme
05ffb04768 Merge branch 'feature/SIENTIAPDE-1972-gateway-write-read' into feature/SIENTIAPDE-1972-gateway-wiring 2026-09-22 11:42:37 -03:00
PedroHMCosme
4f4037b4ae fix(gateway): satisfy mypy on nats/grpc adapters and generated proto code
- nats_consumer/grpc_server: annotate nc/sub/server attrs (were inferred
  as None-only from __init__, breaking on the real assignment later).
- active_read: narrow on 'if names:' instead of the derived 'persisted'
  bool so mypy sees names as non-Optional inside the publish_reading call.
- pyproject: exclude ingestor/proto/ (protoc/grpcio-tools output) from
  mypy's file walk and skip following it as an import - it's generated,
  not hand-maintained, and mypy can't see its runtime-built message classes.
2026-09-22 11:42:24 -03:00
PedroHMCosme
a215523fef Merge branch 'feature/SIENTIAPDE-1972-gateway-foundations' into feature/SIENTIAPDE-1972-gateway-write-read 2026-09-22 11:33:48 -03:00
PedroHMCosme
cfa8078334 fix(gateway): don't clobber asyncua's default application_uri with None
Only set application_uri when server_uri is configured; otherwise
asyncua's sane default ('urn:freeopcua:client') stood, but the code
explicitly overwrote it with None. Also fixes mypy strict-optional
error caught by the quality gate.
2026-09-22 11:33:24 -03:00
PedroHMCosme
79258658bc style: ruff format (new quality gate check picked up from main) 2026-09-22 11:29:41 -03:00
PedroHMCosme
0d20f6d123 Merge branch 'feature/SIENTIAPDE-1972-gateway-write-read' into feature/SIENTIAPDE-1972-gateway-wiring 2026-09-22 11:28:06 -03:00
PedroHMCosme
6f4b04e8c0 style: ruff format (new quality gate check picked up from main) 2026-09-22 11:27:55 -03:00
PedroHMCosme
05732c66b8 Merge branch 'feature/SIENTIAPDE-1972-gateway-foundations' into feature/SIENTIAPDE-1972-gateway-write-read 2026-09-22 11:26:37 -03:00
PedroHMCosme
cdf7521530 style: ruff format (new quality gate check picked up from main) 2026-09-22 11:26:26 -03:00
PedroHMCosme
b8d3a5118b Merge branch 'feature/SIENTIAPDE-1972-gateway-write-read' into feature/SIENTIAPDE-1972-gateway-wiring
# Conflicts:
#	.gitignore
#	docs/superpowers/plans/2026-07-13-opc-gateway.md
2026-09-22 11:19:50 -03:00
PedroHMCosme
33b961a5cf Merge branch 'feature/SIENTIAPDE-1972-gateway-foundations' into feature/SIENTIAPDE-1972-gateway-write-read
# Conflicts:
#	docs/superpowers/plans/2026-07-13-opc-gateway.md
2026-09-22 11:18:36 -03:00
PedroHMCosme
23b40cac81 chore: untrack local planning docs (superpowers specs/plans), gitignore them 2026-09-22 11:16:48 -03:00
PedroHMCosme
4700030547 Merge branch 'feature/SIENTIAPDE-1972-gateway-write-read' into feature/SIENTIAPDE-1972-gateway-wiring
# Conflicts:
#	README.md
#	requirements.txt
2026-09-22 10:55:23 -03:00
PedroHMCosme
61d8f8da9c Merge branch 'feature/SIENTIAPDE-1972-gateway-foundations' into feature/SIENTIAPDE-1972-gateway-write-read 2026-09-22 10:48:44 -03:00
PedroHMCosme
3dcc59f65e Merge remote-tracking branch 'origin/main' into feature/SIENTIAPDE-1972-gateway-foundations
# Conflicts:
#	ingestor/ingestor.py
#	ingestor/managers/data_manager.py
#	requirements.txt
#	tests/unit/managers/test_data_manager.py
2026-09-22 10:47:13 -03:00
6df354f505 ci(deploy): Configure env_list_path as a list 2026-09-11 00:33:34 -03:00
github-actions[bot]
7c28c147ca chore: bump version to 1.4.4 2026-09-10 14:29:54 +00:00
Bruno Domingues
a1aa7b51e1 Merge pull request #35 from Aignosi/fix/SIENTIAPDE-2068
Implement DataOps Worker Deployment & Workflow Refinements
2026-09-10 11:29:31 -03:00
0aa39e3b0c SIENTIAPDE-2068: Implement DataOps Worker deployment workflow, remove legacy release workflow, and enforce 'chart-ref' label on pull requests. 2026-09-10 11:12:53 -03:00
9d23416b79 Merge pull request #34 from Aignosi/fix/SIENTIAPDE-2072
SIENTIAPDE-2072: bump sientia_do pin to 1.12.2
2026-08-25 16:31:09 -03:00
Eduardo Rios
68dc8bd6d5 SIENTIAPDE-2072: bump sientia_do pin to 1.12.2
Picks up the notification timestamp -> native datetime fix.
2026-08-17 16:42:16 -03:00
810bf54d56 fix(ingestor): Remove __del__ methods for async shutdown 2026-08-05 15:25:06 -03:00
ef37122f56 ci(workflow): Enhance quality gate, streamline validation, and add AI guidance
- **Quality Gate (.github/workflows/quality-gate.yml):**
- Expanded push triggers to include main, release/**, and feature/** branches.
- Added concurrency control to cancel in-progress runs, preventing redundant checks.
- Refined workflow permissions to be more specific (contents: read, pull-requests: write, issues: write), enhancing security.
- **Local Validation (validate.sh):**
- Removed the validate.sh script, as its checks are now integrated into or superseded by the CI pipeline.
- **AI Guidance (CLAUDE.md):**
- Introduced CLAUDE.md to provide comprehensive guidance for Claude Code, detailing project architecture, commands, and conventions for AI assistants.
- **SonarQube Configuration (sonar-project.properties):**
- Removed hardcoded sonar.projectVersion.
2026-08-05 15:08:00 -03:00
497abe5582 Merge pull request #30 from Aignosi/fix/SAM0123-231
Remove asyncua Version Constraint
2026-07-24 08:24:43 -03:00
f0ac6c2702 git push
Merge branch 'fix/SAM0123-231' of github.com:Aignosi/sientia-dataops-opc-ingestor into fix/SAM0123-231
2026-07-23 16:18:39 -03:00
a239a1a706 SAM0123-231: Enhance OPC UA client setup by asserting certificate and private key presence and assigning pod ID to client description. 2026-07-23 16:18:28 -03:00
ab2f105c62 Merge branch 'main' into fix/SAM0123-231 2026-07-23 16:13:26 -03:00
f099091bee Merge branch 'main' into fix/SAM0123-231 2026-07-23 16:11:04 -03:00
08a76a9293 SAM0123-231: Remove version pin for asyncua in requirements.txt 2026-07-23 16:10:51 -03:00
c29b06288c Merge pull request #29 from Aignosi/fix/SAM0123-231
Python Dependency Refactor, Local Dev Enhancements, and OPC UA Cert Automation
2026-07-23 14:15:24 -03:00