refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)

Solution + 23 src projects + 26 test projects renamed; folders, csproj,
namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated.
ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated.
SQL roles/logins, LDAP domains, CLI command name, and CLI config dir
(~/.scadalink → ~/.scadabridge) also renamed.

Build green; 5 Host.Tests fail awaiting SQL login rename in next commit.
Pre-existing StaleTagMonitor timing flakes unchanged.

Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
Joseph Doherty
2026-05-28 09:37:45 -04:00
parent 6d87ee3c3b
commit 7b0b9c7365
1531 changed files with 11180 additions and 11054 deletions
+9 -9
View File
@@ -1,6 +1,6 @@
# Test Infrastructure
This document describes the local Docker-based test infrastructure for ScadaLink development. Seven services provide the external dependencies needed to run and test the system locally. The first seven run in `infra/docker-compose.yml`; Traefik runs alongside the cluster nodes in `docker/docker-compose.yml`.
This document describes the local Docker-based test infrastructure for ScadaBridge development. Seven services provide the external dependencies needed to run and test the system locally. The first seven run in `infra/docker-compose.yml`; Traefik runs alongside the cluster nodes in `docker/docker-compose.yml`.
## Services
@@ -25,12 +25,12 @@ docker compose up -d
After the first startup, run the SQL setup and seed scripts:
```bash
docker exec -i scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaLink_Dev1#' -C \
docker exec -i scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaBridge_Dev1#' -C \
-i /docker-entrypoint-initdb.d/setup.sql
docker exec -i scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaLink_Dev1#' -C \
docker exec -i scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaBridge_Dev1#' -C \
-i /docker-entrypoint-initdb.d/machinedata_seed.sql
```
@@ -59,13 +59,13 @@ For use in `appsettings.Development.json`:
```json
{
"ConnectionStrings": {
"ScadaLinkConfig": "Server=localhost,1433;Database=ScadaLinkConfig;User Id=scadalink_app;Password=ScadaLink_Dev1#;TrustServerCertificate=true",
"ScadaLinkMachineData": "Server=localhost,1433;Database=ScadaLinkMachineData;User Id=scadalink_app;Password=ScadaLink_Dev1#;TrustServerCertificate=true"
"ScadaBridgeConfig": "Server=localhost,1433;Database=ScadaBridgeConfig;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true",
"ScadaBridgeMachineData": "Server=localhost,1433;Database=ScadaBridgeMachineData;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true"
},
"Ldap": {
"Server": "localhost",
"Port": 3893,
"BaseDN": "dc=scadalink,dc=local",
"BaseDN": "dc=scadabridge,dc=local",
"UseSsl": false
},
"OpcUa": {
@@ -85,7 +85,7 @@ For use in `appsettings.Development.json`:
"TestApi": {
"BaseUrl": "http://localhost:5200",
"AuthMode": "ApiKey",
"ApiKey": "scadalink-test-key-1"
"ApiKey": "scadabridge-test-key-1"
}
}
}
+30 -30
View File
@@ -2,7 +2,7 @@
## Overview
The test database uses Microsoft SQL Server 2022 Developer Edition running in Docker. It provides two empty databases for ScadaLink — schema creation is handled by EF Core migrations at application startup (dev mode).
The test database uses Microsoft SQL Server 2022 Developer Edition running in Docker. It provides two empty databases for ScadaBridge — schema creation is handled by EF Core migrations at application startup (dev mode).
## Image & Ports
@@ -14,21 +14,21 @@ The test database uses Microsoft SQL Server 2022 Developer Edition running in Do
| Account | Username | Password | Purpose |
|---------|----------|----------|---------|
| SA | `sa` | `ScadaLink_Dev1#` | Server admin (setup only) |
| App | `scadalink_app` | `ScadaLink_Dev1#` | Application login (db_owner on both databases) |
| SA | `sa` | `ScadaBridge_Dev1#` | Server admin (setup only) |
| App | `scadabridge_app` | `ScadaBridge_Dev1#` | Application login (db_owner on both databases) |
## Databases
| Database | Purpose |
|----------|---------|
| `ScadaLinkConfig` | Configuration Database component — templates, deployments, users, audit log |
| `ScadaLinkMachineData` | Machine/operational data storage |
| `ScadaBridgeConfig` | Configuration Database component — templates, deployments, users, audit log |
| `ScadaBridgeMachineData` | Machine/operational data storage |
Both databases are created by `infra/mssql/setup.sql`. EF Core migrations populate the `ScadaLinkConfig` schema. The `ScadaLinkMachineData` database is seeded with sample tables and stored procedures by `infra/mssql/machinedata_seed.sql`.
Both databases are created by `infra/mssql/setup.sql`. EF Core migrations populate the `ScadaBridgeConfig` schema. The `ScadaBridgeMachineData` database is seeded with sample tables and stored procedures by `infra/mssql/machinedata_seed.sql`.
## Data Persistence
SQL data is stored in the named Docker volume `scadalink-mssql-data`. Data survives container restarts and `docker compose down`. To reset the database completely:
SQL data is stored in the named Docker volume `scadabridge-mssql-data`. Data survives container restarts and `docker compose down`. To reset the database completely:
```bash
docker compose down -v
@@ -41,16 +41,16 @@ docker compose up -d
After the first `docker compose up -d`, run the setup script:
```bash
docker exec -i scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaLink_Dev1#' -C \
docker exec -i scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaBridge_Dev1#' -C \
-i /docker-entrypoint-initdb.d/setup.sql
```
This creates the databases and the `scadalink_app` login. Then seed the Machine Data database with sample tables, stored procedures, and data:
This creates the databases and the `scadabridge_app` login. Then seed the Machine Data database with sample tables, stored procedures, and data:
```bash
docker exec -i scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaLink_Dev1#' -C \
docker exec -i scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaBridge_Dev1#' -C \
-i /docker-entrypoint-initdb.d/machinedata_seed.sql
```
@@ -61,11 +61,11 @@ You only need to run these once (or again after deleting the volume).
For `appsettings.Development.json`:
```
Server=localhost,1433;Database=ScadaLinkConfig;User Id=scadalink_app;Password=ScadaLink_Dev1#;TrustServerCertificate=true
Server=localhost,1433;Database=ScadaBridgeConfig;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true
```
```
Server=localhost,1433;Database=ScadaLinkMachineData;User Id=scadalink_app;Password=ScadaLink_Dev1#;TrustServerCertificate=true
Server=localhost,1433;Database=ScadaBridgeMachineData;User Id=scadabridge_app;Password=ScadaBridge_Dev1#;TrustServerCertificate=true
```
## Verification
@@ -73,23 +73,23 @@ Server=localhost,1433;Database=ScadaLinkMachineData;User Id=scadalink_app;Passwo
1. Check the container is running:
```bash
docker ps --filter name=scadalink-mssql
docker ps --filter name=scadabridge-mssql
```
2. Query using `sqlcmd` inside the container:
```bash
docker exec -it scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaLink_Dev1#' -C \
docker exec -it scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U sa -P 'ScadaBridge_Dev1#' -C \
-Q "SELECT name FROM sys.databases"
```
3. Verify the app login:
```bash
docker exec -it scadalink-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U scadalink_app -P 'ScadaLink_Dev1#' -C \
-d ScadaLinkConfig \
docker exec -it scadabridge-mssql /opt/mssql-tools18/bin/sqlcmd \
-S localhost -U scadabridge_app -P 'ScadaBridge_Dev1#' -C \
-d ScadaBridgeConfig \
-Q "SELECT DB_NAME()"
```
@@ -112,17 +112,17 @@ python infra/tools/mssql_tool.py check
python infra/tools/mssql_tool.py setup --script infra/mssql/setup.sql
# List tables in a database
python infra/tools/mssql_tool.py tables --database ScadaLinkConfig
python infra/tools/mssql_tool.py tables --database ScadaBridgeConfig
# Run an ad-hoc query
python infra/tools/mssql_tool.py query --database ScadaLinkConfig --sql "SELECT name FROM sys.tables"
python infra/tools/mssql_tool.py query --database ScadaBridgeConfig --sql "SELECT name FROM sys.tables"
```
Use `--host`, `--port`, `--user`, `--password` to override defaults (localhost:1433, sa, ScadaLink_Dev1#). Run with `--help` for full usage.
Use `--host`, `--port`, `--user`, `--password` to override defaults (localhost:1433, sa, ScadaBridge_Dev1#). Run with `--help` for full usage.
## Machine Data Tables & Stored Procedures
The `machinedata_seed.sql` script creates the following in `ScadaLinkMachineData`:
The `machinedata_seed.sql` script creates the following in `ScadaBridgeMachineData`:
**Tables**:
@@ -145,13 +145,13 @@ The `machinedata_seed.sql` script creates the following in `ScadaLinkMachineData
| `usp_GetEquipmentEvents` | Get recent equipment events with optional filters |
| `usp_GetActiveAlarms` | Get active/acknowledged alarms by severity |
## Relevance to ScadaLink Components
## Relevance to ScadaBridge Components
- **Configuration Database** — primary consumer; EF Core context targets `ScadaLinkConfig`.
- **Deployment Manager** — reads/writes deployment records in `ScadaLinkConfig`.
- **Template Engine** — reads/writes template definitions in `ScadaLinkConfig`.
- **Security & Auth** — user/role data stored in `ScadaLinkConfig`.
- **External System Gateway** — scripts use `Database.Connection("machineDataConnection")` to query `ScadaLinkMachineData` tables and stored procedures.
- **Configuration Database** — primary consumer; EF Core context targets `ScadaBridgeConfig`.
- **Deployment Manager** — reads/writes deployment records in `ScadaBridgeConfig`.
- **Template Engine** — reads/writes template definitions in `ScadaBridgeConfig`.
- **Security & Auth** — user/role data stored in `ScadaBridgeConfig`.
- **External System Gateway** — scripts use `Database.Connection("machineDataConnection")` to query `ScadaBridgeMachineData` tables and stored procedures.
- **Site Runtime** — scripts call stored procedures via `Database.Connection()` and `Database.CachedWrite()` for batch recording and data queries.
- **Inbound API** — methods can query machine data via named database connections.
+22 -22
View File
@@ -2,7 +2,7 @@
## Overview
The test LDAP server uses [GLAuth](https://glauth.github.io/), a lightweight LDAP server backed by a TOML config file. It provides test users and groups that map to ScadaLink's role-based authorization model.
The test LDAP server uses [GLAuth](https://glauth.github.io/), a lightweight LDAP server backed by a TOML config file. It provides test users and groups that map to ScadaBridge's role-based authorization model.
## Image & Ports
@@ -12,20 +12,20 @@ The test LDAP server uses [GLAuth](https://glauth.github.io/), a lightweight LDA
## Base DN
```
dc=scadalink,dc=local
dc=scadabridge,dc=local
```
## Test Users
All users have the password `password`.
| Username | Email | Primary Group | Additional Groups | ScadaLink Role |
| Username | Email | Primary Group | Additional Groups | ScadaBridge Role |
|----------|-------|---------------|-------------------|----------------|
| `admin` | admin@scadalink.local | SCADA-Admins | — | Full administrator |
| `designer` | designer@scadalink.local | SCADA-Designers | — | Template designer |
| `deployer` | deployer@scadalink.local | SCADA-Deploy-All | — | Deploy to all sites |
| `site-deployer` | site-deployer@scadalink.local | SCADA-Deploy-SiteA | — | Deploy to SiteA only |
| `multi-role` | multi-role@scadalink.local | SCADA-Admins | SCADA-Designers, SCADA-Deploy-All | Multiple roles |
| `admin` | admin@scadabridge.local | SCADA-Admins | — | Full administrator |
| `designer` | designer@scadabridge.local | SCADA-Designers | — | Template designer |
| `deployer` | deployer@scadabridge.local | SCADA-Deploy-All | — | Deploy to all sites |
| `site-deployer` | site-deployer@scadabridge.local | SCADA-Deploy-SiteA | — | Deploy to SiteA only |
| `multi-role` | multi-role@scadabridge.local | SCADA-Admins | SCADA-Designers, SCADA-Deploy-All | Multiple roles |
## Groups
@@ -41,36 +41,36 @@ All users have the password `password`.
Users bind with their full DN, which includes the primary group as an OU:
```
cn=<username>,ou=<PrimaryGroupName>,ou=users,dc=scadalink,dc=local
cn=<username>,ou=<PrimaryGroupName>,ou=users,dc=scadabridge,dc=local
```
For example: `cn=admin,ou=SCADA-Admins,ou=users,dc=scadalink,dc=local`
For example: `cn=admin,ou=SCADA-Admins,ou=users,dc=scadabridge,dc=local`
The full DNs for all test users:
| Username | Full DN |
|----------|---------|
| `admin` | `cn=admin,ou=SCADA-Admins,ou=users,dc=scadalink,dc=local` |
| `designer` | `cn=designer,ou=SCADA-Designers,ou=users,dc=scadalink,dc=local` |
| `deployer` | `cn=deployer,ou=SCADA-Deploy-All,ou=users,dc=scadalink,dc=local` |
| `site-deployer` | `cn=site-deployer,ou=SCADA-Deploy-SiteA,ou=users,dc=scadalink,dc=local` |
| `multi-role` | `cn=multi-role,ou=SCADA-Admins,ou=users,dc=scadalink,dc=local` |
| `admin` | `cn=admin,ou=SCADA-Admins,ou=users,dc=scadabridge,dc=local` |
| `designer` | `cn=designer,ou=SCADA-Designers,ou=users,dc=scadabridge,dc=local` |
| `deployer` | `cn=deployer,ou=SCADA-Deploy-All,ou=users,dc=scadabridge,dc=local` |
| `site-deployer` | `cn=site-deployer,ou=SCADA-Deploy-SiteA,ou=users,dc=scadabridge,dc=local` |
| `multi-role` | `cn=multi-role,ou=SCADA-Admins,ou=users,dc=scadabridge,dc=local` |
## Verification
1. Check the container is running:
```bash
docker ps --filter name=scadalink-ldap
docker ps --filter name=scadabridge-ldap
```
2. Test a user bind with `ldapsearch`:
```bash
ldapsearch -H ldap://localhost:3893 \
-D "cn=admin,ou=SCADA-Admins,ou=users,dc=scadalink,dc=local" \
-D "cn=admin,ou=SCADA-Admins,ou=users,dc=scadabridge,dc=local" \
-w password \
-b "dc=scadalink,dc=local" \
-b "dc=scadabridge,dc=local" \
"(objectClass=*)"
```
@@ -78,9 +78,9 @@ ldapsearch -H ldap://localhost:3893 \
```bash
ldapsearch -H ldap://localhost:3893 \
-D "cn=admin,ou=SCADA-Admins,ou=users,dc=scadalink,dc=local" \
-D "cn=admin,ou=SCADA-Admins,ou=users,dc=scadabridge,dc=local" \
-w password \
-b "dc=scadalink,dc=local" \
-b "dc=scadabridge,dc=local" \
"(cn=multi-role)"
```
@@ -114,14 +114,14 @@ python infra/tools/ldap_tool.py search --filter "(cn=multi-role)"
Use `--host` and `--port` to override defaults (localhost:3893). Run with `--help` for full usage.
## Relevance to ScadaLink Components
## Relevance to ScadaBridge Components
- **Security & Auth** — test LDAP bind authentication, group-to-role mapping, and multi-group resolution.
- **Central UI** — test login flows with different role combinations.
## Notes
- GLAuth uses plain LDAP on port 3893. ScadaLink's Security & Auth component requires LDAPS/StartTLS in production. For dev testing, configure the LDAP client to allow plaintext connections.
- GLAuth uses plain LDAP on port 3893. ScadaBridge's Security & Auth component requires LDAPS/StartTLS in production. For dev testing, configure the LDAP client to allow plaintext connections.
- To add users or groups, edit `infra/glauth/config.toml` locally and restart the container: `docker compose restart ldap`. Note that the file is named `config.toml` on the host but is mounted into the container as `/app/config/config.cfg` (the path GLAuth expects).
- The `admin` user is configured with `[[users.capabilities]]` (`action = "search"`, `object = "*"`) in the GLAuth config. This grants the admin account permission to perform LDAP search operations, which is required for user/group lookups.
- Anonymous bind is not allowed. All LDAP operations (including searches) require an authenticated bind. Use the `admin` account for search operations.
+9 -9
View File
@@ -2,7 +2,7 @@
## Overview
The test OPC UA server uses [Azure IoT OPC PLC](https://github.com/Azure-Samples/iot-edge-opc-plc), a simulated OPC UA server that generates realistic data. It is configured with custom nodes that match ScadaLink attribute patterns.
The test OPC UA server uses [Azure IoT OPC PLC](https://github.com/Azure-Samples/iot-edge-opc-plc), a simulated OPC UA server that generates realistic data. It is configured with custom nodes that match ScadaBridge attribute patterns.
## Image & Ports
@@ -10,8 +10,8 @@ Two identical OPC UA server instances run with the same tag configuration, on di
| Instance | OPC UA Endpoint | Web UI | Container |
|----------|----------------|--------|-----------|
| opcua | `opc.tcp://localhost:50000` | `http://localhost:8080` | scadalink-opcua |
| opcua2 | `opc.tcp://localhost:50010` | `http://localhost:8081` | scadalink-opcua2 |
| opcua | `opc.tcp://localhost:50000` | `http://localhost:8080` | scadabridge-opcua |
| opcua2 | `opc.tcp://localhost:50010` | `http://localhost:8081` | scadabridge-opcua2 |
- **Image**: `mcr.microsoft.com/iotedge/opc-plc:latest`
@@ -30,7 +30,7 @@ Two identical OPC UA server instances run with the same tag configuration, on di
## Custom Nodes
The file `infra/opcua/nodes.json` defines a single `ConfigFolder` object (not an array) with a root "ScadaLink" folder containing four equipment subfolders. Tags match typical ScadaLink instance attribute patterns:
The file `infra/opcua/nodes.json` defines a single `ConfigFolder` object (not an array) with a root "ScadaBridge" folder containing four equipment subfolders. Tags match typical ScadaBridge instance attribute patterns:
| Folder | Tags | Types |
|--------|------|-------|
@@ -44,14 +44,14 @@ All custom nodes hold their initial/default values (0 for numerics, false for bo
Custom nodes live in namespace 3 (`http://microsoft.com/Opc/OpcPlc/`). Node IDs follow the pattern `ns=3;s=<Folder>.<Tag>` (e.g., `ns=3;s=Motor.Speed`). Nested folders use dot notation: `ns=3;s=JoeAppEngine.Scheduler.ScanTime`.
The browse path from the Objects root is: `OpcPlc > ScadaLink > Motor|Pump|Tank|Valve|JoeAppEngine`.
The browse path from the Objects root is: `OpcPlc > ScadaBridge > Motor|Pump|Tank|Valve|JoeAppEngine`.
## Verification
1. Check both containers are running:
```bash
docker ps --filter name=scadalink-opcua
docker ps --filter name=scadabridge-opcua
```
2. Verify both OPC UA endpoints using any OPC UA client (e.g., UaExpert, opcua-commander):
@@ -83,7 +83,7 @@ python infra/tools/opcua_tool.py check
python infra/tools/opcua_tool.py browse
# Browse a specific equipment folder
python infra/tools/opcua_tool.py browse --path "3:OpcPlc.3:ScadaLink.3:Motor"
python infra/tools/opcua_tool.py browse --path "3:OpcPlc.3:ZB.MOM.WW.ScadaBridge.3:Motor"
# Read a tag value
python infra/tools/opcua_tool.py read --node "ns=3;s=Motor.Speed"
@@ -99,12 +99,12 @@ Use `--endpoint` to override the default endpoint (`opc.tcp://localhost:50000`).
```bash
python infra/tools/opcua_tool.py --endpoint opc.tcp://localhost:50010 check
python infra/tools/opcua_tool.py --endpoint opc.tcp://localhost:50010 browse --path "3:OpcPlc.3:ScadaLink.3:Motor"
python infra/tools/opcua_tool.py --endpoint opc.tcp://localhost:50010 browse --path "3:OpcPlc.3:ZB.MOM.WW.ScadaBridge.3:Motor"
```
Run with `--help` for full usage.
## Relevance to ScadaLink Components
## Relevance to ScadaBridge Components
- **Data Connection Layer** — connect to this server to test OPC UA subscription, read/write, and reconnection behavior.
- **Site Runtime / Instance Actors** — deploy instances with tag mappings pointing at these nodes.
+10 -10
View File
@@ -35,7 +35,7 @@ var browser = await playwright.Chromium.ConnectAsync("ws://localhost:3000");
var page = await browser.NewPageAsync();
// Browser runs inside Docker — use the Docker network hostname for Traefik.
await page.GotoAsync("http://scadalink-traefik");
await page.GotoAsync("http://scadabridge-traefik");
```
### Node.js
@@ -44,7 +44,7 @@ await page.GotoAsync("http://scadalink-traefik");
const { chromium } = require('playwright');
const browser = await chromium.connect('ws://localhost:3000');
const page = await browser.newPage();
await page.goto('http://scadalink-traefik');
await page.goto('http://scadabridge-traefik');
```
### Python
@@ -55,18 +55,18 @@ from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.connect("ws://localhost:3000")
page = browser.new_page()
page.goto("http://scadalink-traefik")
page.goto("http://scadabridge-traefik")
```
## Central UI Access
The Playwright container is on the `scadalink-net` Docker network, so it can reach the Central UI cluster nodes directly:
The Playwright container is on the `scadabridge-net` Docker network, so it can reach the Central UI cluster nodes directly:
| Target | URL in Test Scripts |
|--------|---------------------|
| Traefik LB | `http://scadalink-traefik` |
| Central Node A | `http://scadalink-central-a:5000` |
| Central Node B | `http://scadalink-central-b:5000` |
| Traefik LB | `http://scadabridge-traefik` |
| Central Node A | `http://scadabridge-central-a:5000` |
| Central Node B | `http://scadabridge-central-b:5000` |
**Important**: The browser runs inside the Docker container, so `page.goto()` URLs must use Docker network hostnames (not `localhost`). The test script itself connects to the Playwright server via `ws://localhost:3000` (host-mapped port), but all URLs navigated by the browser resolve inside the container.
@@ -75,13 +75,13 @@ The Playwright container is on the `scadalink-net` Docker network, so it can rea
1. Check the container is running:
```bash
docker ps --filter name=scadalink-playwright
docker ps --filter name=scadabridge-playwright
```
2. Check the server is accepting connections (look for the WebSocket endpoint in logs):
```bash
docker logs scadalink-playwright 2>&1 | head -5
docker logs scadabridge-playwright 2>&1 | head -5
```
3. Quick smoke test with a one-liner (requires `npx` and `playwright` on the host):
@@ -90,7 +90,7 @@ docker logs scadalink-playwright 2>&1 | head -5
npx playwright@1.58.2 test --browser chromium --connect ws://localhost:3000
```
## Relevance to ScadaLink Components
## Relevance to ScadaBridge Components
- **Central UI** — end-to-end UI testing of all Blazor Server pages (login, admin, design, deployment, monitoring workflows).
- **Traefik Proxy** — verify load balancer behavior, failover, and active node routing from a browser perspective.
+6 -6
View File
@@ -2,7 +2,7 @@
## Overview
The test REST API server is a lightweight Python/Flask application that provides HTTP endpoints matching the patterns used by ScadaLink's External System Gateway and Inbound API components. It supports simple parameter/response methods, complex nested object/list methods, authentication, and error simulation.
The test REST API server is a lightweight Python/Flask application that provides HTTP endpoints matching the patterns used by ScadaBridge's External System Gateway and Inbound API components. It supports simple parameter/response methods, complex nested object/list methods, authentication, and error simulation.
## Image & Ports
@@ -20,7 +20,7 @@ The test REST API server is a lightweight Python/Flask application that provides
The server validates requests using one of two methods:
- **API Key**: `X-API-Key: scadalink-test-key-1` header
- **API Key**: `X-API-Key: scadabridge-test-key-1` header
- **Basic Auth**: Any username/password (accepts all credentials)
The `GET /api/Ping` endpoint is always unauthenticated (health check).
@@ -35,7 +35,7 @@ For `appsettings.Development.json` (External System Gateway):
"TestApi": {
"BaseUrl": "http://localhost:5200",
"AuthMode": "ApiKey",
"ApiKey": "scadalink-test-key-1"
"ApiKey": "scadabridge-test-key-1"
}
}
}
@@ -149,7 +149,7 @@ Response: `{"batchId": "BATCH-A1B2C3D4", "accepted": true, "itemCount": 2}`
1. Check the container is running:
```bash
docker ps --filter name=scadalink-restapi
docker ps --filter name=scadabridge-restapi
```
2. Test the health endpoint:
@@ -162,7 +162,7 @@ curl http://localhost:5200/api/Ping
```bash
curl -X POST http://localhost:5200/api/Add \
-H "X-API-Key: scadalink-test-key-1" \
-H "X-API-Key: scadabridge-test-key-1" \
-H "Content-Type: application/json" \
-d '{"a": 2, "b": 3}'
```
@@ -192,7 +192,7 @@ python infra/tools/restapi_tool.py methods
Use `--url` to override the base URL (default: `http://localhost:5200`), `--api-key` for the API key. Run with `--help` for full usage.
## Relevance to ScadaLink Components
## Relevance to ScadaBridge Components
- **External System Gateway** — test HTTP/REST calls (`ExternalSystem.Call()` and `CachedCall()`), API key authentication, error classification (5xx vs 4xx), and timeout handling.
- **Inbound API** — test the `POST /api/{methodName}` pattern, flat JSON parameters, and extended type system (Object, List) with complex nested responses.
+5 -5
View File
@@ -40,8 +40,8 @@ For `appsettings.Development.json` (Notification Service):
> **`Server` host**: use `localhost` only when the Notification Service runs directly on
> the host. When it runs inside the docker cluster, set `Server` to the container name
> `scadalink-smtp` — the cluster compose stack and the infra compose stack share the
> `scadalink-net` network, so the container is reachable by name.
> `scadabridge-smtp` — the cluster compose stack and the infra compose stack share the
> `scadabridge-net` network, so the container is reachable by name.
The delivery service (`MailKitSmtpClientWrapper`) only accepts `Basic` or `OAuth2`
there is no "no auth" mode — so the working config above uses `Basic`:
@@ -70,7 +70,7 @@ Mailpit exposes a REST API at `http://localhost:8025/api` for programmatic acces
1. Check the container is running:
```bash
docker ps --filter name=scadalink-smtp
docker ps --filter name=scadabridge-smtp
```
2. Open the web UI at `http://localhost:8025` to view captured emails.
@@ -100,7 +100,7 @@ python infra/tools/smtp_tool.py check
# Send a test email
python infra/tools/smtp_tool.py send --to user@example.com --subject "Alarm: Tank High Level" --body "Tank level exceeded 95%"
# Send with BCC (matches ScadaLink notification delivery pattern)
# Send with BCC (matches ScadaBridge notification delivery pattern)
python infra/tools/smtp_tool.py send --to scada-notifications@company.com --bcc "operator1@company.com,operator2@company.com" --subject "Shift Report"
# List captured messages
@@ -115,7 +115,7 @@ python infra/tools/smtp_tool.py clear
Use `--host` and `--port` to override SMTP defaults (localhost:1025), `--api` for the Mailpit API URL. Run with `--help` for full usage.
## Relevance to ScadaLink Components
## Relevance to ScadaBridge Components
- **Notification Service** — test SMTP delivery, BCC recipient handling, plain-text formatting, and store-and-forward retry behavior (Mailpit can be stopped/started to simulate transient failures).
- **Store-and-Forward Engine** — verify buffered retry by stopping the SMTP container and observing queued notifications.